iOS内存管理(感悟)
最近闲暇时间对iOS内存管理做了一些整理,希望对那些初入iOS领域的读者有一些帮助。
希望读者指出文中不妥之处,共同进步,谢谢!
众所周知,iOS内存管理是基于引用计数(retainCount)的管理。
注:以下引用计数使用RC替代
1.创建一个对象并获取它的所有权 (通过alloc/new/copy/mutableCopy) RC=1
2.retain RC+1
3.release RC-1
4.当RC=0 系统调用dealloc 方法回收内存
接下来让我们来看看比较重要的的属性修饰符(ARC环境) strong weak assign copy
依次举例说明
Strong
假设我们有一个对象
@property (nonatomic, strong) Student *strongName;
我们来看下它的set方法,系统帮我们实现
我们来分解下
① [strongName retain]; 新值指向内存RC+1
② [_strongName release]; 旧值RC-1
③ _strongName = strongName; 新值和旧值指向一样,持有对象所有权
我们再看看图
图① 图② 图③weak 和 assign
假设我们有一个对象
@property (nonatomic, weak) Student *weakStudent;
我们来看下它的set方法,系统帮我们实现
我们来分解下
_weakStudent = weakStudent;新值和旧值指向一样,没有获取对象所有权
注:weak 和 assign set方法一样,区别weak指针当对象没有强引用时,置nil,安全,用在对象类型,比如代理形成循环引用时 需要 @property(nonatomic, weak) id delegate;
assign指针当对象没有强引用时,不会置nil,会形成野指针,访问程序会崩溃,一般用于基本数据类型,这是因为基本数据类型分配在栈内存,由系统回收。
copy
假设我们有一个对象
@property (nonatomic, copy) Student *StudentCopy;
我们来看下它的set方法,系统帮我们实现
我们来分解下
① [_StudentCopy release]; 旧值 RC-1
② _StudentCopy = [StudentCopy copy]; 新值拷贝一份内容,新的地址赋值给旧值, _StudentCopy指向内存RC = 1, 获取对象所有权。
我们再看看图
图① 图②引申:
为什么NSString 一般用 copy来修饰?@property(nonatomic, copy) NSString *name;
这是因为如果使用Strong修饰符的话,可能会因为外部的变量修改,会修改到你的成员变量
让我们回归代码:
@property (nonatomic, strong) NSString *strongName;
之前我们说过了,系统实现的set方法应该是这样
假设我们定义一个临时字符串NSMutableString,初始内容@“aaa”,并传递给全局变量 self.strongName,这时self.strongName的内容也是@”aaa“
我们修改它,这时临时字符串内容为@”aaasss“,这时我们的全局变量self.strongName的内容也被修改为@”aaasss“
让我们再看看图
如果使用copy @property (nonatomic, copy) NSString *strongName;
成员变量就不会被修改,这是因为拷贝出新的指针,不会被修改
如图
最后再次感谢各位读者!