iOS 属性中strong,weak,assign,retain,copy等特性

时间:2022-02-18 17:05:36

导语:

在初学iOS的时候,不明白property中属性有什么作用,比如strong, weak, assign, retain, copy等特性。

一、 Objective-C程序员的基本内存管理模型有三种

  1. 自动垃圾收集(现在Apple不建议使用垃圾收集,建议使用ARC进行代替)
  2. 手动引用计数和自动释放池
  3. 自动引用计数(ARC, Xcode4.2发布了自动引用计数之后,我们几乎可以不再需要考虑内存管理的问题)


二、 手工管理内存计数

如果不打算使用ARC,就得学习引用计数工作的原理


当创建一个对象时,初始的引用计数为1,为保存对象的存在,每当创建引用 -> 对象需要将引用数加1,通过给对象发送retain消息实现,当不需要对象时,通过发送release,为引用计数减1。当对象的引用计数为0时,系统就会释放它的内存。(释放内存由系统的自动释放池来实现,我们所需要做得主要就是对引用加1减1操作)

[myFraction retain]; //引用计数加1

//中间一系列对myFraction的操作

[myFraction release]; //引用计数减1


在手动引用计数环境中,可以添加assign,retain,copy特性


当我们使用以下这条命令时

self.property = newValue;


assign特性会是: 

property = newValue;

assign用于简单赋值,不更改索引计数

对基础数据类型 (例如NSInteger,CGFloat)和C数据类型(int, float, double, char, 等)适用简单数据类型



retain特性会是: 

if (property != newValue){
[property release];
property = [newValue retain];
}

retain:释放旧的对象,将旧对象的值赋予输入对象,再提高输入对象的索引计数为1

此属性只能用于Objective-C对象类型,而不能用于Core Foundation对象。



copy特性会是:

if (property != newValue){
[property release];
property = [newValue copy];
}

copy:建立一个索引计数为1的对象,然后释放旧对象,在赋值时使用传入值的一份拷贝。



三、自动引用计数(ARC)

  1. 强变量(strong)

相当于老版本的retain,而且可以不再需要做release操作了

只要有强变量的引用,对象就不会释放内存。


2.弱变量(weak)

相当于老版本的assign。但是只适应于对象

当弱变量引用的对象被别的变量释放,那么弱变量会被自动设置为nil,这样可以有效地防止崩溃


3.strong 和 copy的区别

// on someObject:
@property (nonatomic, strong) NSString *text;
@@property (nonatomic, copy) NSString *textTwo;

//省略
. . .

NSMutableString *m = [NSMutableString stringWithString:@"Strawberry"];
someObject.text = m;
someObject.textTwo = m;
// at this point, someObject.text is @"Strawberry"
[m appendString:@" and banana"];
// now both m and someObject.text are @"Strawberry and banana",but someObject.textTwo is still @"Strawberry"

因为执行someObject.text = m时,实际上是把指针指向了m所指向的对象,所以m和someObject.text指针指向同一个对象。

而someObject.textTwo则是先将m中的对象copy了一份,然后再指向这个copy,所以并不会因为m变化而变化。

注意上文说的copy特性,是建立一个索引为1的对象。


4. 如果是新手,实在要用strong特性来申请NSString。那必须注意以下代码

someObject.text = [[NSString alloc] initWithString:m];
//这行代码的意思就是申请一个新的NSString指针,然后指向一个string值和m值相同的对象。类似copy特性


四、总结

(在ARC环境下)

  1. 对基础数据类型 (例如NSInteger,CGFloat)和C数据类型(int, float, double, char, 等)适合用assign特性
  2. 对于NS开头,UI开头的对象引用 比如(NSMutableArray *,NSMutableDictionary * ,NSMutableString *,UIImage *, UIColor *等)可以用strong特性
  3. 对于NSArray、NSDictionary、NSString最好用copy类型。
  4. 对UI控件的引用,iOS会自动将其设置为弱变量(weak)。