__strong 修飾符
??? __strong 修飾符實 id 類型和對象類型默認的所有權修飾符刁卜。也就是說,以下源代碼中的 id變量礁哄,實際上被附加了所有權修飾符长酗。
id obj = [[NSObject alloc] init];
??? id 和對象類型在沒有明確指定所有權修飾符時,默認為 __strong 修飾符桐绒。上面的源代碼與一下相同夺脾。
id __strong obj = [[NSObject alloc] init];
??? 如“strong”這個名稱所示,__strong 修飾符表示對對象的“強引用”茉继。持有強引用的變量在超出其作用域時被廢棄咧叭,隨著強引用失效,引用的對象會隨之釋放烁竭。
??? 以下關注源代碼中關于對象的所有者的部分:
{
??? id __strong obj = [[NSObject alloc] init];
}
?? 該對象的所有者如下:
{? // 自己生成并持有對象
? id __strong obj = [[NSObject alloc] init];
// 因為變量 obj 為強引用菲茬,所以自己持有對象
? }? /* 因為變量 obj 超出其作用域,強引用失效派撕,所以自動地釋放自己持有的對象婉弹。對象的所有者不存在,因此廢棄终吼。*/
??? 此處镀赌,對象的所有者和對象的生存周期是明確的。那么际跪,在取得非自己生成切持有的對象時商佛,如下:
{
????? id __strong obj = [NSMutableArray array];
}
??? 在 NSMuatbleArray 類的 array 類方法的源代碼中取得非自己生成并持有的對象具體如下:
{ // 取得非自己生成且持有的對象
????? id __strong obj = [NSMutableArray array];
??? // 因為變量 obj 為強引用,所以自己持有對象
} /* 因為變量 obj 超出其作用域姆打,強引用失效良姆,所以自動地釋放自己持有的對象 */
??? 在這里對象的所有者和對象的生存周期也是明確的。
{ // 自己生成并持有的對象
????? id __strong obj = [[NSObject alloc] init];
??? // 因為變量 obj 為強引用幔戏,所以自己持有對象玛追。
} /* 因為變量obj 超出其作用域,強引用失效评抚,所以自動地釋放自己持有的對象豹缀。對象的所有者不存在,因此廢棄該對象慨代。
??? 當然,剛有 __strong 修飾符的變量之間可以相互賦值
??? id __strong obj0 = [[NSObject alloc] init];
??? id __strong obj1 = [[NSObject alloc] init];
??? id __strong obj2 = nil;
??? obj0 = obj1;
??? obj2 = obj1;
??? obj1 = nil;
??? obj0 = nil;
??? obj2 = nil;
??? 下面來看一下生成并持有對象的強引用:
??? id __strong obj0 = [[NSObject alloc] init]; // 對象 A
??? // obj0 持有對象 A 的強引用
??? id __strong obj1 = [[NSObject alloc] init]; // 對象 B
??? // obj1 持有對象 B 的強引用
??? id __strong obj2 = nil;
??? // obj2 不持有任何對象
??? obj0 = obj1;
??? /* obj0 持有由 obj1 賦值的對象 B 的強引用啸如,因為 obj0 被賦值侍匙,所以原先持有的對對象 A 的強引用失效。對象 A 的所有者不存在,因此廢棄對象 A 想暗。此時妇汗,持有對象 B 的強引用的變量為 obj0 和 obj1。*/
??? obj2 = obj0;
??? /* obj2 持有由 obj0 賦值的對象 B 的強引用说莫,此時杨箭,持有對象 B? 的強引用的變量為 obj0, obj1 和 obj2 */
??? obj1 = nil;
??? /* 因為 nil 被賦予了 obj1,所以對對象 B 的強引用失效储狭。此時互婿,持有對象 B 的強引用的變量為 obj0 和 obj2 */
??? obj0 = nil;
? /* 因為 nil 被賦予了 obj0,所以對對象 B 的強引用失效辽狈。此時慈参,持有對象 B 的強引用的變量為 obj2 */
??? obj2 = nil;
? ? /* 因為 nil 被賦予了 obj0,所以對對象 B 的強引用失效刮萌。對象 B 的所有者不存在驮配,因此廢棄對象 B */
??? 通過以上內(nèi)容不難發(fā)現(xiàn),__strong 修飾符的變量着茸,不僅只在變量作用域中壮锻,在賦值上也能夠爭取的管理其對象的所有者。
??? 當然涮阔,即便是 Objective-C 類成員變量猜绣,也可以在方法參數(shù)上,使用附有 __strong 修飾符的變量澎语。
@interface Test : NSObject
{??? id __strong obj_;
??? - (void)setObject:(id __Strong)obj;
}
@end
@implementation Test
- (id)init
{??
??? self = [super init];
??? return self;
}
- (void)setObject:(id __strong)obj
{
??? obj_ = obj;
}
@end
??? 下面是這使用該類
{
? ? id __strong test = [[Tetst alloc] init]; ??
??? [test setObject:[[NSObject alloc] init]];
}
??? 該例中聲稱并持有對象的狀態(tài)如下:
{
??? id __strong test = [[Tetst alloc] init];
??? // test 持有 Test 對象的強引用
??? [test setObject:[[NSObject alloc] init]];
??? // Test 對象的 obj_ 成員途事, 持有 NSObject 對象的強引用
}? /* 因為 test 變涼量超出作用域,強引用失效擅羞,所以自動釋放 Test 對象尸变。 Test 對象的所有者不存在,所以廢棄减俏。 廢棄Test 的同時召烂,Test 的對象 obj_ 成員也被廢棄, NSObject 對象的強引用失效娃承,自動釋放 NSObject 對象奏夫。 NSObject 對象的所有者不存在,因此廢棄 */
??? 通過 __strong 修飾符历筝,不必再次輸入 retain 或者release酗昼,完美地滿足了“引用計數(shù)式內(nèi)存管理的思考式”:
1.自己生成的對象,自己持有梳猪;
2.非自己生成的對象麻削,自己也能持有;
3.不再需要自己持有的對象時釋放;
4.非自己持有的對象無法釋放呛哟。
??? 前兩項“自己生成的對象叠荠,自己持有”和“非自己生成的對象,自己也能持有”扫责,只需通過對帶 __strong修飾符的變量賦值便可達成榛鼎。通過廢棄帶 __strong 修飾符的變量(變量作用域結束或是成員變量所屬對象廢棄)或者對變量賦值,都可以做到“不再需要自己持有的對象時釋放”鳖孤。最后一項“非自己持有的對象無法釋放”者娱,由于不必再次輸入 release,所以根本就不會執(zhí)行淌铐。這些都滿足于引用計數(shù)式內(nèi)存管理的思考方式肺然。
??? 因為 id 類型和對象類型的所有權修飾符默認為 __strong 修飾符,所以不需要寫上 “__strong”腿准。
?// 結束际起,是另一種開始。
?// 作者會將所讀所學摘錄及分享
?// 本文參考《Objcetive-C高級編程iOS與OS X多線程和內(nèi)存管理》