从weak表中获取废弃对象的地址为键值的记录。
将包含在记录中的所有附有__weak修饰符变量的地址,赋值为nil
从weak表中删除该记录。
从引用计数表中删除废弃对象的地址作为键值的记录。
根据以上步骤,前面说的如果附有__weak修饰符的变量所引用的对象被废弃,则将nil赋值给该变量这一功能即被实现。由此可知,如果大量使用附有__weak修饰符的变量,则会消耗相应的CPU资源,对此只在需要避免循环引用的时候使用__weak修饰符。
使用__weak修饰符时,以下代码会引起编译器警告
{
id __weak obj = [[NSObject alloc] init];
NSLog(@"obj = %@",obj);
}
编译结果如下:
Assigning retained object to weak variable; object will be released after assignment
编译器模拟代码如下:
id obj;
id temp = objc_msgSend(NSObject,@selector(alloc));
objc_msgSend(temp,@selector(init));
objc_initWeak(&obj,temp);
objc_release(temp);
objc_destroyWeak(&obj);
运行结果如下:
2017-12-07 19:37:24.075939+0800 ImageOrientation[10963:3581164] obj = (null)
使用附有__weak修饰符的变量,即是使用注册到autoreleasepool中的对象。
{
id __weak obj1 = obj;
NSLog(@"%@",obj1);
}
该代码可以转换为如下形式:
/** 编译器模拟代码*/
id obj1;
objc_initWeak(&obj1,obj);
id temp = objc_loadWeakRetained(&obj1);
objc_autorelease(temp);
NSLog(@"%@",obj1);
objc_destroyWeak(&obj1);
与赋值时相比,在使用附有__weak修饰符变量的情形下,增加了对objc_loadWeakRetained函数和objc_autorelease函数的调用。这些函数的动作如下:
objc_loadWeakRetained函数取出附有__weak修饰符变量所引用的对象并retain objc_autorelease函数将对象注册到autoreleasepool中。__autoreleasing 修饰符
将对象赋值给附有__autoreleasing修饰符的变量等同于MRC时调用对象的autorelease方法。
@autoreleasepool{
id __autoreleasing obj = [[NSObject alloc] init];
}
模拟代码如下:
/** 编译器的模拟代码 */
id pool = objc_autoreleasePoolPush();
id obj = objc_msgSend(NSObject,@selector(alloc));
objc_msgSend(obj,@selector(init));
objc_autoreleas(obj);
objc_autoreleasePoolPop(pool);
alloc/new/copy/mutableCopy之外的方法实现:
@autoreleasepool{
id __autoreleasing obj = [NSMutableArray array];
}
/** 编译器的模拟代码 */
id pool = objc_autoreleasePoolPush();
id obj = objc_msgSend(NSMutableArray,@selector(array));
objc_retainAutorelesedReturnedValue(obj);
objc_autorelease(obj);
objc_autoreleasePoolPop(pool);










