当前位置: 首页 > news >正文

【iOS】OC高级编程 iOS多线程与内存管理阅读笔记——自动引用计数(三)

目录

ARC规则

概要

所有权修饰符

__strong修饰符

__weak修饰符

__unsafe_unretained修饰符

__autoreleasing修饰符


ARC规则

概要

“引用计数式内存管理”的本质部分在ARC中并没有改变,ARC只是自动地帮助我们处理“引用计数”的相关部分。

在编译单位上可以设置ARC有效或无效。

所有权修饰符

ARC有效时,非基本类型上必须附加所有权修饰符,一共有四种:

  • __strong修饰符

  • __weak修饰符

  • __unsafe _unretained修饰符

  • __autoreleasing修饰符

__strong修饰符

__strong修饰符是非基础类型默认的所有权修饰符,也就是说,非基础类型在没有明确指定所有权修饰符时,默认为__strong修饰符。

{id __strong obj = [[NSObject alloc] init];
}

此源代码明确指定了变量的作用域,ARC无效时,该源代码可记述如下:

{id obj = [[NSObject alloc] init];[obj release];
}

这里增加了调用release方法的代码,同之前ARC有效时的动作一样,如代码所示:附有__strong修饰符的变量obj在超出其变量作用域时,会释放其被赋予的对象。__strong修饰符表示对对象的“强引用”,持有强引用的变量在超出其作用域时被废弃,随着强引用的失效,引用的对象会随之释放。

自己生成并持有对象时:

{id __strong obj = [[NSObject alloc] init];//变量obj为强引用,所以自己持有对象
}
//obj超出其作用域,强引用失效,所以自动释放自己持有的对象。
//对象的所有者不存在,因此废弃该对象

取得非自己生成并持有的对象时:

{id __strong obj = [NSMutableArray array];//obj为强引用,所以自己持有对象
}//因为变量obj超出其作用域,强引用失效,所以自动释放自己持有的对象

附有__strong修饰符的变量之间可以相互赋值\

id __strong obj0 = [[NSObject alloc] init];
id __strong obj1 = [[NSObject alloc] init];
id __strong obj2 = nil;
obj0 = obj1;
obj2 = obj0;
obj1 = nil;
obj0 = nil;
obj2 = nil;

下面来看一下生成并持有对象的强引用:

id __strong obj0 = [[NSObject alloc] init];
//obj0持有对象A的强引用
id __strong obj1 = [[NSObject alloc] init];
//obj1持有对象B的强引用
id __strong obj2 = nil;
//obj2不持有任何对象
obj0 = obj1;
//obj0持有由obj1赋值的对象B的强引用
//obj0被赋值,原先持有的对对象A的强引用失效
//对象A的所有者不存在,因此废弃对象A
//此时持有对象B的强引用的变量为obj0和obj1。
obj2 = obj0;
//obj2持有由obj0赋值的对象B的强引用
//此时,持有对象B的强引用的变量为obj0,obj1和obj2。
obj1 = nil;
//因为nil被赋予了obj1,所以对对象的B的强引用失效
//此时持有对象B的强引用的变量为obj0和obj2。
obj0 = nil;
//因为nil被赋予obj0,所以对对象B的强引用失效
//此时持有对象B的强引用的变量为obj2;
obj2 = nil;
//因为nil被赋予obj2,所以对对象B地强引用失效
//对象B的所有者不存在,因此废弃对象B

可见,__strong修饰符的变量,不仅只在变量作用域中,在赋值上也能够正确地管理其对象的所有者。并且,OC类成员变量也可以在方法参数上使用附有__strong修饰符的变量。

@interface Test : NSObject
{id __strong obj_;
}
@end
​
@implementation Test
- (id)init {self = [super init];return self;
}
​
- (void)setObject:(id __strong)obj {obj_ = obj;
}
@end;

使用这个类:

{id __strong test = [[Test alloc] init];[test setObject:[[NSObject alloc] init]];
}

该例中生成并持有对象的状态记录如下:

{id __strong test = [[Test alloc] init];//test持有对象Test对象的强引用[test setObject:[[NSObject alloc] init]];//Test对象的obj_成员,持有NSObject对象的强引用
}//因为test变量超出其作用域,强引用失效,所以自动释放Test对象。//Test对象的所有者不存在,因此废弃该对象
​//废弃Test对象时,Test对象obj_成员也被废弃,NSObject对象的强引用失效,自动释放NSObject对象。//NSObject对象的所有者不存在,因此废弃该对象

像这样,可以直接使用于类成员变量以及方法参数中。另外,__strong、__weak、__autoreleasing这三种修饰符,可以保证将附有这些修饰符的自动变量初始化为nil。

因为id类型和对象类型的所有权修饰符默认为__strong修饰符,所以不需要写上这个修饰符。

__weak修饰符

仅仅通过__strong修饰符进行内存管理会发生“循环引用”的问题,如下图所示:

比如前面出现的带有__strong修饰符的成员变量在持有对象时,很容易发生循环引用。

@interface Test : NSObject {id __strong obj_;
}
- (void)setObject:(id __strong)obj;
@end
​
@implementation Test 
- (id)init {self = [super init];return self;
}
​
- (void)setObject:(id __strong)obj {obj_ = obj;
}
@end

以下为循环引用


{id test0 = [[Test alloc] init];id test1 = [[Test alloc] init];[test0 setObject:test1];[test1 setObject:test0];
}

分析一下这里生成并持有对象的状态

{id test0 = [[Test alloc] init];//test0持有Test对象A的强引用id test1 = [[Test alloc] init];//test1持有Test对象B的强引用[test0 setObject:test1];//Test对象A的obj_成员变量持有Test对象B的强引用//此时持有Test对象B的强引用的变量为Test对象A的obj_和test1[test1 setObject:test0];//Test对象B的obj_成员变量持有Test对象A的强引用//此时持有Test对象A的强引用的变量为Test对象B的obj_和test0
}
//test0变量超出作用域,强引用失效,所以自动释放Test对象A
//test1变量超出作用域,强引用失效,所以自动释放Test对象B
//此时持有Test对象A的强引用的变量为Test对象B的obj_
//此时持有Test对象B的强引用的变量为Test对象A的obj_
//发生内存泄漏

由于这里在test0和test1所持有的对象在生命周期结束后,还被分别被test1和test0的属性所持有,所以对象在超出生命周期后本应被废弃却没有被废弃。

循环引用容易发生内存泄漏。所谓内存泄漏就是说应当废弃的对象在超出其生存周期后继续存在。

像下面这样,虽然只有一个对象,但在该对象持有自身时,也会发生循环引用(自引用)

id test = [[Test alloc] init];
[test setObject:test];

这时就需要__weak修饰符来避免循环引用。

__weak修饰符与__strong修饰符相反,提供弱引用,不持有对象实例。

当变量加上__weak修饰符时,如果编译以下代码,编译器会发生警告。

id __weak obj = [[NSObject alloc] init];

此源代码将自己生成并持有的对象赋值给附有__weak修饰符的变量obj,变量obj持有对持有对象的弱引用。因此为了不以自己持有的状态来保存自己生成并持有的对象,生成的对象会立即被释放。编译器对此会给出警告。但如果像下面这样,将对象赋给附有__strong修饰符的变量之后再赋值给附有__weak修饰符的变量,就不会发生警告了。

{id __strong obj0 = [[NSObject alloc] init];id __weak obj1 = obj0;
}

下面分析对象的持有状况

{id __strong obj0 = [[NSObject alloc] init];//因为obj0变量为强引用,所以自己持有对象id __weak obj1 = obj0;//obj1变量持有生成对象的弱引用
}
//因为obj0变量超出作用域,强引用失效,所以自动释放自己持有的对象
//因为对象所有者不存在,所以废弃该对象

__weak修饰符的变量不持有对象,所以在超出其变量作用域时,对象即被释放。将先前可能发生循环引用的类成员变量改为附有__weak修饰符的成员变量的话,可以避免循环引用现象。

除此之外,__weak修饰符还有另一优点,就是在持有某对象的弱引用时,如果该对象被废弃,则此弱引用将自动失效且处于nil被赋值的状态(空弱引用)。如以下代码所示:

id __weak obj1 = nil;{id __strong obj0 = [[NSObject alloc] init];obj1 = obj0;NSLog(@"A:%@",obj1);
}
NSLog(@"B:%@", obj1);

执行结果如下:

下面分析一下对象的持有情况:

id __weak obj1 = nil{id __strong obj0 = [[NSObject alloc] init];//obj0变量为强引用,所以自己持有对象obj1 = obj0;//obj1变量持有对象的弱引用NSLog(@"A:%@", obj1);//输出obj1变量持有的弱引用的对象
}
//因为obj0变量超出作用域,强引用失效,所以自动释放自己持有的对象。
//对象无持有者,所以废弃该对象
//废弃对象的同时,持有该对象弱引用的obj1变量的弱引用失效,nil赋值给obj1

像这样,使用_weak修饰符可避免循环引用。并且可以通过检查附有__weak修饰符的变量是否为nil,来判断被赋值的对象是否已废弃。

但是,__weak修饰符只能用于iOS5以上及OS X Lion以上版本的应用程序。在iOS4以及OS X Snow Leopard的应用程序中可使用__unsafe_unretained修饰符来代替。

__unsafe_unretained修饰符

__unsafe_unretained修饰符是一个不安全的所有权修饰符。附有__unsafe_unretained修饰符的变量不属于编译器的内存管理对象。将自己生成并持有的对象赋值给附有__unsafe_unretained修饰符的变量中,编译器会给出适当的警告。附有__unsafe_unretained修饰符的变量,因为自己生成并持有的对象不能继续为自己所有,所以生成的对象会立即被释放。在如下代码中__weak修饰符和__unsafe_unretained修饰符就有一些差异了。

id __unsafe_unretained obj1 = nil;
{id __strong obj0 = [[NSObject alloc] init];obj1 = obj0;NSLog(@"A:%@", obj1);
}
NSLog(@"B:%@", obj1);

代码的执行结果如下:

来分析一下对象的持有情况:

 

id __unsafe_unretained obj1 = nil;
{id __strong obj0 = [[NSObject alloc] init];//因为obj变量为强引用,所以自己持有对象obj1 = obj0;//虽然obj0变量赋值给obj1,但是obj1变量既不持有对象的强引用也不持有弱引用NSLog(@"A: %@", obj1);
}//因为obj0变量超出作用域,强引用失效,所以自动释放自己持有的对象//因为对象无持有者,所以废弃该对象
NSLog(@"B:%@", obj1);
//obj1变量表示的对象已经被废弃(悬垂指针)!
//错误访问

也就是说,最后一行的NSLog只是碰巧正常运行,虽然访问了已经被废弃的对象,但程序在个别运行状况下才会崩溃。

在使用__unsafe_unretained修饰符时,赋值给附有__strong修饰符的变量时有必要确定被赋值的对象确实存在。

__autoreleasing修饰符

ARC有效时,不能使用autorelease方法,也不能使用NSAutoreleasePool类。虽然不能直接使用autorelease,但实际上ARC有效时autorelease功能是起作用的。

ARC无效时:

NSAutoreleasePool *pool = [[NSAutoreleasePoll alloc] init];
id obj = [[NSObject alloc] init];
[obj autorelease];
[pool drain];

ARC有效时:

@autoreleasepool {id __autoreleasing obj = [[NSObject alloc] init];
}

指定"@autoreleasepool块"来替代“NSAutoreleasePool类对象生成、持有以及废弃“这一范围。ARC有效时,要通过将对象赋值给附加了__autoreleasing修饰符的变量来替代调用autorelease方法。对象赋值给附有__autoreleasing修饰符的变量等价于在ARC无效时调用对象的autorelease方法,即对象被注册到autoreleasepool。

一般不显式地附加__autoreleasing修饰符。

在使用alloc/new/copy/mutableCopy以外的方法来取得对象时,编译器会检查方法名是否已alloc/new/copy/mutableCopy开始,如果不是则自动将返回值的对象注册到autoreleasepool。另外,init方法返回值的对象不注册到autoreleasepool。

@autoreleasepool {id __strong obj = [NSMutableArray array];
}

分析一下对象的所有状况

@autoreleasepool {//取得非自己生成并持有的对象id __strong obj = [NSMutableArray array];//因为变量obj为强引用,所以自己持有对象//该对象由编译器判断其方法名后自动注册到autoreleasepool
}//因为变量obj超出其作用域,强引用失效,自动释放自己持有的对象//同时随着@autoreleasepool块的结束,注册到autoreleasepool中的所有对象被自动释放//对象的所有者不存在,对象被废弃
分析一下为什么取得非自己生成并持有对象时,不使用__autoreleasing修饰符也能使对象注册到autoreleasepool。以下为源代码示例:+ (id)array {return [[NSMutableArray alloc] init];
}

也可以写成:

+ (id)array {id obj = [[NSMutableArray alloc] init];return obj;
}

这里id obj的所有权修饰符默认为__strong,当return是的对象变量超出作用域时,该强引用对应的自己持有的对象会被自动释放。但该对象作为函数的返回值,编译器会自动将其注册到autoreleasepool。

另外,在访问附有__weak修饰符的变量时,也必定要访问注册到autoreleasepool的对象。

id __weak obj1 = obj0;
NSLog(@"class = %@", [obj1 class]);

以下源代码与此相同

id __weak obj1 = obj0;
id __autoreleasing tmp = obj1;
NSLog(@"class=%@", [tmp class]);

为什么访问附有__weak修饰符的变量时必须访问注册到autoreleasepool的对象呢?因为__weak修饰符只持有对象的弱引用,而在访问引用对象的过程中,该对象可能被废弃。如果把要访问的对象注册到autoreleasepool中,那么在@autoreleasepool块结束之前都能确保该对象存在。因此在使用附有__weak修饰符的变量时就必定要使用注册到autoreleasepool中的对象。

最后,id的指针例如id *obj也是非显式地使用__autoreleasing修饰符的例子,id *obj,即id __autoreleasing *obj。同样,对象的指针NSObject **obj便成为了NSObject * __autoreleaseing *obj。

像这样,id的指针或对象的指针在没有显式指定时会被附加上__autoreleasing修饰符。

比如,为了得到详细的错误信息,经常会在方法的参数重传递NSError对象的指针,而不是函数返回值。Cocoa框架中,大多方法也是用这种方式。如NSString的stringWithContentsOfFile:encoding:error类方法等。使用该方法的代码如下所示:

NSError *error = nil;
BOOL result = [obj performOperationWithError:&error];

id指针或对象的指针会默认附加上__autoreleasing修饰符。

作为alloc/new/copy/mutableCopy方法返回值取得的对象是自己生成并持有的,其他情况下便是取得非自己生成并持有的对象。因此,使用附有__autoreleasing修饰符的变量作为对象取得参数,与除alloc/new/copy/mutableCopy外其他方法的返回值取得对象完全一样,都会注册到autoreleasepool,并取得非自己生成并持有的对象。

比如performOperationWithError方法的源代码应该是下面这样:

-- (BOOL)performOperationWithError:(NSError* __autoreleasing *)error {//错误发生*error = [[NSError alloc] initwithDomain:MyAppDomain code:errorCode userInfo:nil];return NO;}

因为声明为NSError* __autoreleasing *类型的error作为 *error被赋值,所以能够返回注册到autoreleasepool中的对象。

然而,下面这样的源代码会产生编译器错误

NSError *error = nil;
NSError **pError = &error;

因为赋值给对象指针时,所有权修饰符必须一致。

前面的方法参数中使用了附有__autoreleasing修饰符的对象指针类型,然而调用方却使用了附有__strong修饰符的对象指针类型。那为什么该源代码没有警告就顺利通过编译了呢?实际上,编译器自动将该源代码转化成了下面形式:

NSError __strong *error = nil;
NSError __autoreleasing *tep = error;
BOOL result = [obj performOperationWithError:&tmp];
error = tep;

当然也可以显式地指定方法参数中对象指针类型的所有权修饰符。

- (BOOL) performOperationWithError:(NSError* __strong *)error;

像该源代码的声明一样,对象不注册到autoreleasepool也能传递,但是为了在使用参数取得对象时,贯彻内存管理的思考方式,我们要将参数声明为附有__autoreleasing修饰符的对象指针类型。

另外,虽然可以非显式地指定__autoreleasing修饰符,但在显式地指定__autoreleasing修饰符时,必须注意对象变量要为自动变量(包括局部变量、函数以及方法参数)。

另外,ARC无效时,可将NSAutoreleasePool对象嵌套使用。

NSAutoreleasePool *pool0 = [[NSAutoreleasePool alloc] init];NSAutoreleasePool *pool1 = [[NSAutoreleasePool alloc] init];NSAutoreleasePool *pool2 = [[NSAutoreleasePool alloc] init];id obj = [[NSObject alloc] init];[obj autorelease];[pool2 drain];[pool1 drain];
[pool0 drain];

同样,@autoreleasepool块也能够嵌套使用

@autoreleasepool {@autoreleasepool {@autoreleasepool {id __autoreleasing obj = [[NSObject alloc] init];}}
}

相关文章:

【iOS】OC高级编程 iOS多线程与内存管理阅读笔记——自动引用计数(三)

目录 ARC规则 概要 所有权修饰符 __strong修饰符 __weak修饰符 __unsafe_unretained修饰符 __autoreleasing修饰符 ARC规则 概要 “引用计数式内存管理”的本质部分在ARC中并没有改变,ARC只是自动地帮助我们处理“引用计数”的相关部分。 在编译单位上可以…...

Oracle数据库使用dblink是时出现 ORA-12170:TNS:连接超时

原因: 我遇到这种情况是因为dblink那端的数据库被我重新导了一下dmp,然后本地这边查询就报错了。 解决办法: 把已有的dblink删掉或者说是换个名字,然后按照原来的再新建一个同名的dblink就解决了。...

OpenHarmony系统中实现Android虚拟化、模拟器相关的功能,包括桌面显示,详细解决方案

在 OpenHarmony 系统中实现 Android 虚拟化 和 模拟器功能(面显包括桌示)是一个复杂的任务,涉及多个关键技术栈的集成和深度定制。我们可以通过多种方式来实现 Android 系统的虚拟化和模拟器功能,类似于在普通操作系统中运行虚拟机…...

决策曲线分析(DCA)中平均净阈值用于评价模型算法(R自定义函数)

决策曲线分析(DCA)中平均净阈值用于评价模型算法 DCA分析虽然不强调用来评价模型算法或者变量组合的优劣,但是实际应用过程中感觉DCA曲线的走势和模型的效能具有良好的一致性,其实这种一致性也可以找到内在的联系,比如…...

《经验分享 · 软考系统分析师》

📢 大家好,我是 【战神刘玉栋】,有10多年的研发经验,致力于前后端技术栈的知识沉淀和传播。 💗 🌻 CSDN入驻不久,希望大家多多支持,后续会继续提升文章质量,绝不滥竽充数…...

记录一下 js encodeURI和encodeURIComponent URL转码问题

escape:由于它已经被废弃,不建议在任何新的代码中使用。encodeURI:当你需要对整个URI进行编码时使用,例如在将整个URL作为参数传递时。encodeURIComponent:当你需要编码URI中的某一部分,尤其是查询字符串参…...

【C语言】二维前缀和/求子矩阵之和

相信你是最棒哒!!! 目录 一、题目描述 正确代码 二、题目描述 题目代码 总结 一、题目描述 输入一个 𝑛 行 𝑚 列的整数矩阵,再输入 𝑞个询问,每个询问包含四个整数 𝑥1…...

SRS 服务器入门:实时流媒体传输的理想选择

在当今视频流媒体需求爆炸式增长的时代,如何选择一款高效、稳定且功能强大的流媒体服务器成为了许多开发者和企业关注的焦点。而 SRS(Simple Realtime Server)作为一款开源的流媒体服务器,以其卓越的性能和灵活的功能,…...

【ETCD】【源码阅读】configurePeerListeners() 函数解析

configurePeerListeners 是 ETCD 的一个核心函数,用于为集群中节点之间的通信配置监听器(Peer Listener)。这些监听器主要负责 Raft 协议的消息传递、日志复制等功能。函数返回一个包含所有监听器的列表。 函数签名 func configurePeerList…...

1_ssrf总结

content 什么是ssrf?简介原理 危害利用内网访问端口扫描fsockopenurlbypass127.0.0.0被禁止绕过302跳转DNS重绑定绕过 file协议dict协议gopher协议主从复制打redis打mysql打fastcgi协议打未授权redis Defence 什么是ssrf? 简介 SSRF(Server-Side Request Forger…...

深入解析 Redis

1. 为什么 Redis 性能至关重要? 在现代分布式应用中,Redis 被广泛作为缓存系统、消息队列、实时数据存储和会话管理等多种场景的解决方案。作为一个高性能的内存数据库,Redis 的设计理念是提供低延迟和高吞吐量的操作。然而,当 R…...

Visual Studio 2022发布UWP应用证书绑定失败

最近发布UWP应用时,卡在了关联产品这步,一直提示网络链接问题,获取不到产品信息。创建新项目也是这样,猜测低版本的VS不支持发布UWP应用了,便升级到了VS2022。VS2022创建新UWP工程确实可以关联发布应用,并成…...

K8S对接ceph的RBD块存储

1 PG数量限制问题 1.1 原因分析 1.还是老样子,先创建存储池,在初始化为rbd。 [rootceph141~]# ceph osd pool create wenzhiyong-k8s 128 128 Error ERANGE: pg_num 128 size 3 for this pool would result in 295 cumulative PGs per OSD (2067 tot…...

ragflow连不上ollama的解决方案

由于前期wsl默认装在C盘,后期部署好RagFlow后C盘爆红,在连接ollama的时候一直在转圈圈,问其他人没有遇到这种情况,猜测是因为内存不足无法加载模型导致,今天重新在E盘安装wsl 使用wsl装Ubuntu Win11 wsl-安装教程 如…...

ACL与Prefix List(前缀列表)

匹配工具一般搭配其他操作,可实现NAT,路由策略,策略路由,MQC,流量过滤等操作 通配符掩码 我们都知道子网掩码的1是精确匹配,1是大致匹配,1必须连续 我们也知道反掩码的1是大致匹配&#xff0…...

OpenSSH和OpenSSL升级

需求 centos7.9升级SSH和SSL OpenSSH升级为openssh9.8 OpenSSL升级为openssl-3.4.0 下载openssh最新版本与openssl对应版本 openssh最新版本下载地址 wget https://cdn.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-9.8p1.tar.gzOpenSSL下载地址 这里下载的是3.4.0 wg…...

数据库继续学习

数据库中的外键约束的作用是什么? 外键约束用于在多表操作中保证数据的一致性、完整性和正确性。它确保引用的数据在主表中存在,从而避免孤立记录的出现。 物理外键与逻辑外键的选择? 推荐使用逻辑外键。逻辑外键是指在应用程序层面上实现外键…...

车载以太网-UDPNM

文章目录 UDPNM定义在车载以太网中的作用网络节点状态监测唤醒和睡眠管理网络拓扑发现工作流程消息发送消息接收与处理与其他车载网络协议的比较和协作UDPNM的工作原理是什么?1.消息构建与发送原理消息格式构建发送机制2.消息接收与响应原理接收过程响应机制3.状态管理与定时器…...

网页核心页面设计(第8章)

一、伪元素 伪元素是 CSS 中的一种选择器,用于选择某些特定的元素或元素的一部分,而这些元素本身并不存在于文档的结构中。伪元素使得网页设计师可以更灵活地控制样式,从而可以为元素的内容、框架或文本提供额外的样式,增强网页的…...

在PowerShell下运行curl命令出现错误:Invoke-WebRequest : 无法处理参数,因为参数名称“u”具有二义性

今天在Windows 11下测试Nanamq的HTTP API,按照其文档输入: curl -i --basic -u admin:public -X GET "http://localhost:8081/api/v4/subscriptions" 结果出现二义性错误: 而且输入curl --help命令想看看参数说明的时候&#xff…...

医疗花费预测——协方差矩阵和热力图

引言 在医疗数据分析中,预测个人的医疗花费是一个重要的课题。这不仅有助于个人健康管理,也为医疗资源的合理分配提供了数据支持。本篇博客,我们将探讨如何利用协方差矩阵和热力图来分析和预测个人的医疗花费。我们将以DataFountain提供的数…...

react antd tabs router 基础管理后台模版

在构建 React 后台管理系统时,使用标签页的方式展示路由是一种高效且用户友好的设计模式。这种实现方式通常允许用户在多个页面之间快速切换,并保留页面的状态,类似于浏览器的多标签页功能。 需求分析 1.动态标签页:根据用户的导…...

【数据结构——栈与队列】环形队列的基本运算(头歌实践教学平台习题)【合集】

目录😋 任务描述 相关知识 测试说明 我的通关代码: 测试结果: 任务描述 本关任务:编写一个程序实现环形队列的基本运算。 相关知识 为了完成本关任务,你需要掌握: 初始化队列、销毁队列、判断队列是否为空、进队列…...

【数据结构——栈与队列】链栈的基本运算(头歌实践教学平台习题)【合集】

目录😋 任务描述 相关知识 测试说明 我的通关代码: 测试结果: 任务描述 本关任务:编写一个程序实现链栈的基本运算。 相关知识 为了完成本关任务,你需要掌握: 初始化栈、销毁栈、判断栈是否为空、进栈、出栈、取栈…...

GIT CLONE ERROR: remote: [session-ec426a86] Access denied

报错信息: remote: [session-ec426a86] Access denied 错误原因: 1.更换了不同的GIT仓或者账号 2.之前设置了默认账号密码信息 3. git init 只初始化了GIT项目,并没有清空原有的账号密码配置 处理方法: win11需要到个人文件…...

GitHub 正式收录 MoonBit 作为一门通用编程语言!核心用户突破三万!

MoonBit 编程语言正式被 Github 收录!这对于一个仅有两年发展时间的编程语言来说是一种高度认可,期待未来由 MoonBit 编写的项目数量快速增长,早日成为首个由国人研发迈进 10 万➕ 用户的编程语言。 最近用户数已经接近 3 万(数据…...

PHP中GD库的使用

由于我要用到php的验证码 <?php session_start();// 生成验证码 $random_code substr(md5(uniqid(mt_rand(), true)), 0, 6);// 将验证码保存到 session 中 $_SESSION[captcha] $random_code;// 创建图片 $font 6; $image_width 100; $image_height 40;// 创建图像 $…...

docker安装Elasticsearch和Kibana

上传文件 加载tar包 安装 1.安装elasticsearch 通过下面的Docker命令即可安装单机版本的elasticsearch&#xff1a; docker run -d \--name es \-e "ES_JAVA_OPTS-Xms512m -Xmx512m" \-e "discovery.typesingle-node" \-v es-data:/usr/share/elastics…...

【Linux】文件管理必备知识和基本指令

【Linux】文件管理必备知识和基本指令 什么是操作系统什么是文件什么是路径01. ls 指令02. pwd命令03. cd 指令04. touch指令05.mkdir指令&#xff08;重要&#xff09;&#xff1a;06.rmdir指令 && rm 指令&#xff08;重要&#xff09;&#xff1a;rmdir指令rm指令 0…...

欢迪迈手机商城设计与实现

文末获取源码和万字论文&#xff0c;制作不易&#xff0c;感谢点赞支持。 题目&#xff1a;欢迪迈手机商城设计与实现 摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管…...

吉林有做网站的吗/能打开各种网站的搜索引擎

SSM工作原理 SSM&#xff08;SpringSpringMVCMyBatis&#xff09;框架集由Spring、MyBatis两个开源框架整合而成&#xff08;SpringMVC是Spring中的部分内容&#xff09;。常作为数据源较简单的web项目的框架。 Spring Spring就像是整个项目中装配bean的大工厂&#xff0c;在…...

做一门户网站价格/营销宣传方案

一、函数的有用信息在函数内&#xff0c;用 引起来&#xff0c;添加的注释信息可以写函数的功能&#xff0c;以及需要填写和可以扩展的注释词语二、带参数的装饰器及多个装饰器装饰一个函数def timmerout(flag1): # flag1 flagdef timmer(f):def inner(*args,**kwargs):if fla…...

wordpress媒体库插件/网站外链分析工具

本科生毕业论文 基于Python校园网站系统&#xff08;Django框架&#xff09; 开题报告 学 院&#xff1a; 专 业&#xff1a; 计算机科学与技术 年 级&#xff1a; 学生姓名&#xff1a; …...

深圳网站建设企业/防恶意点击软件

由于不懂程序。 所以选择了先做一个静态的网站。在考虑是用table&#xff0c;还是用 divcss 最后选择了table&#xff0c;因为是个仿站&#xff0c;做出来美观效果要尽量一样才可以。 现在网站已经上线一个月&#xff0c;想给自己点时间&#xff0c;第一&#xff0c;把整个页面…...

网站设计的基本步骤和方法/广州网站优化

在我们登录一些网站、应用、游戏时&#xff0c;见到动态验证码的频率越来越多了。最常见的应该就是Google Authenticator&#xff0c;暴雪安全令之类的应用&#xff0c;通过不断变换的动态数字来最大限度的保证账号的数据安全。今天 Gitee 推荐的这款开源项目&#xff0c;是依托…...

网站设计风格的关键词/近几年的网络营销案例

LINUX指令认识 使用XShell远程登录LINUx 查看Linux的ip ifconfig 1.ls[选项][目录文件] 对于目录&#xff0c;列出目录下所以子目录与文件。对于文件&#xff0c;列出文件名以及其他信息 -a 列出目录下的所有文件&#xff0c;包括以 . 开头的隐含文件。 -d 将目录象文件一样显示…...