iOS与OS X内存管理之二:ARC屬性管理
2017-11-04 本文已影响0人
IPFK
聲明的屬性 | 所有權修飾符 |
---|---|
assign | __unsafe_unretianed 修飾符 |
copy | __strong 修飾符(但是賦值是被複製的對象) |
retain | __strong 修飾符 |
strong | __strong 修飾符 |
unsafe_unretianed | __unsafe_unretianed 修飾符 |
weak | __weak修飾符 |
1 __strong 修飾符
- 賦值給__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_retainAutoreleasedReturnValue(obj);//結合上面的圖,可以理解為(已經註冊到pool,然後返回來的方法)
objc_release(obj);
下面分析下NSMutableArray array的實現過程
+ (id ) array
{
return [[NSMutableArray alloc] init];
}
編譯器的模擬代碼如下
+ (id) array
{
id obj = objc_msgSend(NSMutableArray,@selector(alloc));
objc_msgSend(NSMutableArray,@selector(init));
return objc_autoreleaseReturnValue(obj);//結合上圖可以理解為這是開始註冊到pool中的方法(還沒註冊進去!)
}
但是objc_autoreleaseReturnValue與objc_autorelease不同,它不公限於將對象註冊到Pool中,還會檢查是否馬上調用objc_retainAutoreleasedReturnValue方法,如果調用,則未註冊直接返回用,也就是上圖中所示的意思!!!
2 __weak 修飾符
1,若附有__weak 修飾符的變量所引用的對象被廢棄,則將nil賦值給該變量
2,使用附有__weak修飾符的變量,即是使用到autoreleasePool中的變量
{
id __weak obj1 = obj;
NSLog(@"%@",obj1);
}
轉換代碼如下:
id obj1;
objc_initWeak(&obj1,obj);
id tmp = objc_loadWeakRetained(&obj1); //取出weak所引用的對象並retain
objc_autorelease(tmp); //註冊到pool
NSLog(@"%@",tmp);
objc_destroyWeak(&obj1);
由此可知weak修飾符變量所引用的對象在@autoreleasepool結束之前都可以放心使用
{
id __weak o = obj;
NSLog(@"1 %@",o);
NSLog(@"2 %@",o);
NSLog(@"3 %@",o);
NSLog(@"4 %@",o);
NSLog(@"5 %@",o);
}
上面代碼,變量o所賦值的對象obj也被添加到autoreleasepool中五次
可以改成下面形式,這樣就只會添加一次到pool
id __weak o = obj;
id tmp = o;
NSLog(@"1 %@",tmp);
NSLog(@"2 %@",tmp);
NSLog(@"3 %@",tmp);
NSLog(@"4 %@",tmp);
NSLog(@"5 %@",tmp);