标签:
参考:http://blog.csdn.net/hahahacff/article/details/39839571
看了视频、文章后总结一下自己理解的Objective-C的内存管理。
本文从上到下时逐步深入的。
ARC
1.手动内存管理的基本操作函数及原则(黄金法则或配对原则)
内存的开辟和销毁时成对出现的。
在一个代码快中出现了alloc,new,retain,copy,mutabcopy等关键词,当对象不再使用后,就要有对应的release,autorelease 出现与之相对应。
当对象的“引用计数”(retainCount)变为“0”时对象执行dealloc函数,执行销毁操作。
2.当一个类中实例化一个对象时我们可以简单的使用alloc 和 release 解决配对问题。
Person *p = [[Person alloc] init];
[p run];
[p release];
3.当一个类最为另一个类的属性时(被另一个类持有)应该怎样配对呢?
对象 alloc;
被持有;-----------------》 被持有就是执行set方法:所以在set方法中应该retain 对象,在dealloc函数中release对象。
对象 release;
ps. 以上时两对 内存操作。
4.当有两个对象交替被另一个对象持有时改怎样操作呢?
由于交替操作会使第一个被持有的对象造成内存泄露。
所以在第一个被持有的对象在本类中不在使用后立刻release,即在set方法中release 第一个被持有的对象。
代码:
- (void)setCar:(Car *)car
{
[_car release];
_car = [car retain];
}
5. 当同一个对象多次被另一个对象持有时会造成第一个对象被过早释放。(僵尸对象,野指针的出现)(野指针的处理方法是给野指针赋值nil,p = nil)
上面的set方法就会出错。
因此我们需要判断两次持有的对象是不是同一个对象。
代码如下:
- (void)setCar:(Car *)car
{
if(_car != car)
{
[_car release];
_car = [car retain];
}
}
最后的dealloc也需要重写:
- (void)dealloc
{
[_car release];
[super release];//最后调用,因为父类执行release后会将子类销毁,下面的代码就不会执行了,造成内存泄露。子类的真正销毁是在父类中执行的。
//ARC中,可以重写dealloc函数,但是不能写[super release];
}
6.@property的使用
@property 时为简化get,set方法设计的。我们完全可以用展开的get,set 方法代替。
相关参数:
属性关键字 | 使用范围 | 释义 | 是否是默认值 | 小贴士 |
assign | 赋值方式 | 不复制不保留,直接赋值 | YES |
基本数据类型和本类不直接拥有的对象 |
retain | 赋值方式 | 将新值保留一份赋覆盖原值 | NO | 大部分对象可使用 |
copy | 赋值方式 | 将新值复制一份赋覆盖原值 | NO | 字符串选择性使用 |
readwrite | 读写权限 | 生成getter和setter两个方法 | YES | 变量可读取可修改 |
readonly | 读写权限 | 只生成getter方法 | NO | 变量只读不可修改 |
atomic | 原子性 | 原子操作 | YES | 可以保留在多线程环境下,能安全的存取值 |
nonatomic | 原子性 | 非原子操作 | NO | 不生成多线程同步内容 |
getter | 存取方法 | 自定义取方法 | NO | |
setter | 存取方法 | 自定义赋值方法 | NO |
NSString 需要使用copy
@property(nonatomic,copy) NSString *str;
代理中的写法:
@property(nonatomic,assign)id<findapartment> delegate; 因为被代理对象并不是真的持有代理对象,所以为了避免对象的循环引用此处必须使用assign!!
@property(nonatomic,weak) __weak id<findapartment> delegate; ARC中写法。
block中的写法:
@property(nonatomic,retain)int (^changeColor)(int a,int b); MRC
@property(nonatomic,strong)int (^changeColor)(int a,int b); ARC,好像没有什么特殊的%>_<%。。
7.autorelease
autorelease 主要用于类方法的书写中。
(1)ios 5.0以前的创建方式
NSAutoreleasePool *pool=[[NSAutoreleasePool alloc] init];
`````````````````
[pool release];//[pool drain];用于mac
(2)Ios5.0以后,且ARC中只能使用这种方式!!!!
@autoreleasepool
{//开始代表创建自动释放池
·······
}//结束代表销毁自动释放池
8.循环引用
解决方法:
1. 在头文件中用@class 声明类。在m文件中引用文件。
2.两端循环引用的解决方法
一端使用retain,一端使用assign(使用assign的在dealloc中也不用再release)
ARC:
ARC新增两个武功高强的左右护法:strong 和 weak
strong的含义和retain相同,weak和assign相同,修饰完的属性变量用法也是完全没有改变,不过strong和weak只能修饰对象。
苹果官方对于ARC机制中对象的内存引用规则:
(1)任何对象,如果仍有持有者,就不会销毁
(2)任何对象,已经没有任何持有者,即自动销毁
持有者就是指向对象的指针,如果是strong修饰的,即是对象的持有者,如果是weak属性的,则不是持有者
彩蛋:让程序兼容ARC和非ARC部分。转变为非ARC -fno-objc-arc 转变为ARC的, -f-objc-arc 。
标签:
原文地址:http://www.cnblogs.com/vtsay/p/4613422.html