属性声明 | 所有权修饰符 |
---|---|
assign | __unsafe_unretained |
copy | __strong 对象是被复制过来的 |
retain | __strong |
strong | __strong |
unsafe_unretained | __unsafe__unretained |
weak | __weak |
objc_msgSend
objc_release
objc_autoreleaseReturnValue
alloc/new/copy/mutableCopy
的实例创建方法中objc_retainAutoreleasedReturnValue
alloc/new/copy/mutableCopy
之外 的一些实例创建方法源代码 1
{
id __strong obj = [[NSObject alloc] init];
}
// 编译器模拟代码
id obj = objc_msgSend(NSObject, @selector(alloc));
objc_msgSend(obj, @selector(init));
objc_release(obj); // 变量作用域结束时释放对象
源代码 2 - objc_retainAutoreleasedReturnValue
{
id __strong obj = [NSMutableArray array];
}
// 编译器模拟代码
id obj = objc_msgSend(NSMutableArray, @selector(array));
objc_retainAutoreleasedReturnValue(obj);
objc_release(obj);
源代码 3 - objc_autoreleaseReturnValue
+ (id)array {
return [[NSMutableArray alloc] init];
}
// 编译器模拟代码
+ (id)array {
id obj = objc_msgSend(NSMutableArray, @selector(alloc));
objc_msgSend(obj, @selector(init));
return objc_autoreleaseReturnValue(obj);
}
使用 散列表 实现,与 计数引用表相同,weak 表:
key | value |
---|---|
实际上的对象的地址 | __weak 修饰的变量的地址(可有多个,可能用集合或字典实现) |
根据 objc_storeWeak(&weakRef, realObject)
的函数叙述
当 key 为 0 时,表示该 weakRef 要被置 nil
objc_storeWeak(&weakRef, 0)
objc_release
dealloc
_objc_rootDealloc
object_dispose
objc_destructInstance
objc_clear_deallocating
<- Magic Happens Here
由于为 weak 表的弱指针置空包含了赋值操作,因此,若存在大量的 weak 指向,释放对象时,将会消耗大量的 CPU 资源,因此,只应该在需要避免循环引用的情况才使用
源代码 1
{
id __weak obj1 = obj;
}
// 编译器模拟代码
id obj1;
objc_initWeak(&obj1, obj);
objc_destroyWeak(&obj1);
// 将上面的代码再分拆
// objc_initWeak(&obj1, obj);
id obj1 = 0;
objc_storeWeak(&obj1, obj);
// objc_destroyWeak(&obj1);
objc_storeWeak(&obj1, 0);
重点都是有 objc_autorelease
源代码 1 - alloc - init
@autoreleasepool {
id __autorelease obj = [[NSObject alloc] init];
}
// 编译器模拟代码
id pool = objc_autoreleasePoolPush();
id obj = objc_msgSend(NSObject, @selector(alloc));
objc_msgSend(obj, @selector(init));
objc_autorelease(obj);
objc_autoreleasePoolPop(pool);
源代码 2 - 类方法创建
@autoreleasepool {
id __autorelease obj = [NSMutableArray array];
}
// 编译器模拟
id pool = objc_autoreleasePoolPush();
id obj = objc_msgSend(NSMutableArray, @selector(array));
objc_retainAutoreleasedReturnValue(obj);
objc_autorelease(obj);
objc_autoreleasePoolPop(pool);