前言
属性关键字尤为重要, 总结复习。
属性关键字就是用来修饰属性的关键字,保证了程序的正常运行。
1. 属性关键字的分类
- 内存管理有关的关键字:
weak
,assgin
,strong
,retain
,copy
; - 线程安全的关键字:
monatomic
,atomic
- 访问权限的关键字:
readonly
,readwrite
。 - 修饰变量的关键字:
const
,static
,extern
。
2. 内存管理关键字
2.1 weak
weak经常用来OC对象类型的数据,修饰的对象在释放之后,指针地址会自动被置nil,这是弱引用的表现
- ⚠️在ARC的环境下,为了避免循环引用,delegate往往也是weak修饰。在MRC下用assgin修饰。当某个对象不在拥有strong类型的指针指向的时候,对象就会被释放,即使还有weak指针类型指向他,weak指针也会被清除。
2.2 assgin
- assgin常用于非指针变量,用于修饰基础数据类型和C的数据类型 & id类型的数据。用于基本数据类型进行复制操作。
- asssgin不会修改引用计数,也可以用来修饰对象一般不建议如此,因为assgin修饰的对象被释放之后指针的地址还存着,成为了一个没有指向的野指针(垂悬指针)。
⚠️:assgin修饰的基本类型都是基本数据类型,基本数据类型分配在栈上的,栈上的变量是系统自动进行管理,不会造成野指针以及:MRC下的delegate往往assgin,此操作是为了deletage和self等自身产生循环引用。
eg:当对象A通过retain持有了B,B的delegate对象是A,如果都是强引用则导致互相持有无法正确的释放,造成循环引用。
weak和assgin的区别
- 修饰的对象不同:weak修饰OC对象类型的数据,assgin修饰的基本数据变量。
- 引用计数:二者都不会增加引用计数。
- 释放后的结果不同:weak修饰的对象释放之后指针自动为nil避免访问野指针crash,assgin修饰的对象释放之后指针仍然存在,成为野指针。
- 修饰delegate:MRC下assgin, ARC下weak,二者都是为了避免循环引用。
2.3 strong
strong是最常用的修饰符,主要用来修饰OC对象类型的数据:(NSNumber,NSString,NSArray、NSDate、NSDictionary、模型类等)。 strong是强引用,在ARC下等于retain,这一点区别于weak。
strong是我们通常所说的指针拷贝(浅拷贝),内存地址保持不变,只是产生了一个新的指针,新指针和引用对象的指针指向同一个内存地址,没有生成新的对象,多了一个指向该对象的指针。
⚠️:由于使用的是一个内存地址,当该内存地址存储的内容发生变更的时候导致属性也跟着变更。
2.4 copy关键字
同样用于修饰OC对象类型的数据,同时在MRC时期用来修饰block,因为MRC时期block要从栈区copy到堆区。现在的ARC系统自动给我们做了这个操作。也就是现在使用strong或者copy修饰block都可以。
copy和strong相同点在于都是属于强引用,引用计数 + 1,但是copy修饰的对象是内存拷贝,在引用的时候会生成一个新的内存地址和指针,和引用对象完全同,也不会因为引用属性的变更而改变。
copy关键字和strong的区别
copy:内存拷贝-深拷贝,内存地址不同,指针地址也不同。
storng: 指针拷贝-浅拷贝,内存地址不变,指针地址不同。
声明两个copy属性,两个strong属性,分别为可变和不可变类型:
@property(nonatomic,strong)NSString * Strstrong;
@property(nonatomic,copy)NSString * Strcopy;
@property(nonatomic,copy)NSMutableString * MutableStrcopy;
@property(nonatomic,strong)NSMutableString * MutableStrstrong;
1. 不可变对象对属性进行赋值,查看strong修饰和copy修饰的区别
// 不可变对象对属性进行赋值,查看strong修饰和copy修饰的区别
- (void)testNormal {
NSString * OriginalStr = @"我已经开始测试了";
//对 不可变对象赋值 无论是 strong 还是 copy 都是原地址不变,内存地址都为(0x10c6d75c0),生成一个新指针指向对象(浅拷贝)
self.Strcopy = OriginalStr;
self.Strstrong = OriginalStr;
self.MutableStrcopy = OriginalStr;
self.MutableStrstrong = OriginalStr;
// 内容
NSLog(@"原字符串=>%@\n normal:copy=>%@=====strong=