内存管理的思考方式
1.自己生成的对象,自己所持有。
alloc/new/copy/mutableCopy等方法 --生成并持有对象
retain方法 --持有对象
release方法--释放对象
dealloc方法--废弃对象
2.非自己生成的对象,自己也能持有。
//取得对象,但不持有对象
id obj = [NSMutableArray array];
//调用retain方法自己持有对象
[obj retain];
//释放对象
/**
指向对象的指针仍然被保留在变量obj中,貌似可以访问
但对象一经释放绝对不可访问
**/
[obj release];
调用[NSMutableArray array] 方法使取得的对象存在,但自己不持有对象,又是如何实现的呢?
- (id)object
{
//自己持有对象
id obj = [[ NSObject alloc] init];
//取得的对象存在,但自己不持有对象
[ obj autorelease];
return obj;
}
{
//obj变量为强引用,所以自己持有对象
id __strong obj = [[NSObject alloc] init];
//obj1变量持有生成对象的弱引用
id __weak obj1 = obj;
}
//因为obj变量超出作用域,强引用失效,所以自动释放自己持有的对象
//因为对象的所有者不存在,所以废弃改对象
因为__weak修饰的变量不持有对象,所以在超出变量作用域时,对象立即被释放。
__weak修饰符还有另一个优点,。在持有某对象的弱引用时,若该对象被废弃,则此弱引用将自动失效且处于nil被赋值的状态。
id __weak obj1 = nil;
{
//因为obj0变量为强引用,所以自己持有对象
id __strong obj0 = [[NSObject alloc] init];
//obj1变量持有对象的弱引用
obj1 = obj0;
NSLog(@"A: %@", obj1);
}
// 因为obj0变量超出其作用域,强引用失效,所以自动释放自己持有的对象,因为对象无持有者,所以废弃该对象。废弃对象的同时,持有该对象弱引用的obj1变量的弱引用失效,nil赋值给obj1
NSLog(@"B: %@", obj1);
A:<NSObject :0x753e180>
B: (null)
=============================
_autoreleasing 修饰符
ARC 有效时autorelease会如何呢?实际上,在ARC环境下,不能使用autorelease方法。但是,autorelease的功能是起作用的。
在MRC环境下:
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
id obj = [[NSObject alloc] init];
[obj autorelease];
[pool drain];
在ARC环境下:
@autoreleasepool
{
//要将对象赋值给附加了__autoreleasing修饰的变量来代替调用autoreleasing方法
id __autoreleasing obj = [[NSObject alloc] init];
}
@autoreleasepool
{
//obj 强引用, 自己持有对象,并且该对象由编译器判断其方法名后,自动注册到autoreleasepool
id __strong obj = [NSMutableArray array];
}
obj超出作用域,强引用失效,所以自动释放自己持有的对象。
同时随着@autoreleasepool块的结束,注册到autoreleasepool中得所有对象被自动释放。
像这样,不使用__autoreleasing修饰符也能使对象注册到autoreleasepool。
+(id)array
{
id obj = [[NSMutableArray alloc] init];
return obj;
}
由于return 使得对象变量超出其作用域,所以该强引用所对应的自己持有的对象会被自动释放,但该对象作为函数的返回值,编译器会自动将其注册到autoreleasepool.
strong保留此值和weak不保留此值是神马意思?