ARC实现

1.__strong修饰符
{
id __strong obj =[ [NSObject alloc] init];
}
/编译器模拟代码/
id obj = objc_msgSend(NSObject,@selector(alloc));
objc_msgSend(obj,@selector(init));
objc_release(obj);

alloc new copy mutableCopy之外的方法情况:
{
id _strong obj = [NSMutableArray array];
}
/编译器模拟代码/
id obj = objc_msgSend(NSMutableArray,@selector(array));
objc_retainAutoreleaseReturnValue(obj);
objc_release(obj);

objc_retainAutoreleaseReturnValue:用于自己持有(retain)对象的函数,但它持有的对象应为返回注册在autoreleasepool中对象的方法,或是函数的返回值。

NSMutableArray类的array类通过编译器转换
+ (id)array {
return [[NSMutableArray alloc] init];
}
/编译器模拟代码/
id obj = objc_msgSend(NSMutableArray,@selector(alloc));
objc_msgSend(obj ,@selector(init));
return objc_autureleaseReturnValue(obj);

objc_autureleaseReturnValue:会检查使用该函数的方法或函数调用方法的执行命令列表,如果方法或函数的调用方法在调用了方法或函数后紧接着调用objc_retainAutoreleaseReturnValue()函数,那么就不将返回的对象注册到autoreleasepool中,而是直接传递到方法或函数的调用方。objc_retainAutoreleaseReturnValue与objc_retain不同,即使不注册到autoreleasepool中而返回对象,也能够正确获取对象。通过objc_autureleaseReturnValue函数和objc_retainAutoreleaseReturnValue函数的协作,可以不将对象注册到autoreleasepool中而直接传递,这一过程达到了最优化。

2.__weak修饰符
{
id __weak obj1 = obj;
}
/编译器模拟代码/
id obj1;
objc_initWeak(&obj1 ,obj);
objc_destoryWeak(&obj1);

与下列源代码相同
id obj1;
objc_storeWeak(&obj1, obj);
objc_storeWeak(&objc, 0);

废弃谁都不持有对象同时,系统动作:
对象通过objc_release函数释放
(1)objc_release
(2)因为引用计数为0执行dealloc
(3)_objc_rootDealloc
(4)object_dispose
(5)objc_destructInstance
(6)objc_clear_deallocating

对象最后调用的objc_clear_deallocating函数动作如下
(1)从weak表中获取废弃对象的地址为键值的记录
(2)将包含在记录中的所有附有__weak修饰符变量的地址,赋值为nil
(3)从weak表中删除该记录
(4)从引用计数表中删除废弃对象的地址为键值的记录

使用__weak修饰符的变量,既是注册到autoreleasepool中的对象:
{
id __weak obj1 = obj;
NSLog(@"%@",obj1);
}
/编译器模拟代码/
id obj1;
objc_initWeak(&obj1 ,obj);
id tmp = objc_loadWeakRetained(&objc1);
objc_autorelease(tmp);
NSLog(@"%@",tmp);
objc_destoryWeak(&obj1);
与被赋值时相比,使用附有__weak修饰符变量情况下,增加了对objc_loadWeakRetained函数和objc_autorelease函数的调用,动作如下:
(1)objc_loadWeakRetained函数取出附有__weak修饰符变量所引用的对象并retain
(2)objc_autorelease函数将对象注册到autoreleasepool中。

3.__autoreleasing修饰符
将对象赋值给附有__autoreleasing修饰符的变量等同于ARC无效时调用对象的autorelease方法
@autoreleasepool {
id __autoreleasing obj = [[NSObject alloc] init];
}
/编译器模拟代码/
id pool = objc_autoreleasePoolPush();
id obj = msgSend(NSObject,@selector(alloc));
msgSend(obj, @selector(init));
objc_autorelease(obj);
objc_autoreleasePoolPop(pool);

alloc new copy mutableCopy之外的方法情况:
{
id _autoreleasing obj = [NSMutableArray array];
}

/编译器模拟代码/
id pool = objc_autoreleasePoolPush();
id obj = msgSend(NSMutableArray, @selector(array));
objc_retainAutoreleasedReturnValue(obj);
objc_autorelease(obj);
objc_autoreleasePoolPop(pool);
持有对象方法从alloc变为objc_retainAutoreleasedReturnValue函数。

猜你喜欢

转载自blog.csdn.net/xx6109/article/details/83024564
arc