1. NSString *str1 = [NSString stringWithInt: 10];
2. NSString *str2 = [[NSString alloc] initWithInt: 10];
這些方法有什么區別?
uj5u.com熱心網友回復:
歷史可以追溯到不存在自動參考計數的時候。那么蘋果已經創建的符號,即與方法前綴init,copy,new回報所有的指標,那意味著你不需要retain它,其他的方法應該回傳自動釋放的指標。例如
NSString *a;
NSString *b;
@autoreleasepool {
a = [[NSString alloc] initWithFormat:@"%d", 1];
b = [NSString stringWithFormat:@"%d", 2];
NSLog(@"String a in autorelease pool is %@", a); //output: String a in autoreleasepool is 1
NSLog(@"String b in autorelease pool is %@", b); //output: String b in autoreleasepool is 2
}
NSLog(@"String a out of autorelease pool is %@", a); //output: String a out of autorelease pool is 1
NSLog(@"String b in autorelease pool is %@", b); //crash: referencing invalid object, because b was autoreleased but variable `b` still pointing at released object
為了在 autoreleasepool 外部正常作業,b應該保留變數:
NSString *b;
@autoreleasepool {
b = [[NSString stringWithFormat:@"%d", 2] retain];
NSLog(@"String b in autorelease pool is %@", b); //output: String b in autoreleasepool is 2
}
NSLog(@"String b out of autorelease pool is %@", b); //output: String b out of autorelease pool is 1
但是如果使用retain屬性,就會面臨相反的情況:記憶體泄漏。正確的代碼將是
@property (retain) NSString *a;
@property (retain) NSString *b;
@autoreleaspool {
self.a = [[[NSString alloc] initWithFormat:@"%d", 1] autorelease];
self.b = [NSString stringWithFormat:@"%d", 2];
}
如此精確的實施stringWithFormat:做alloc init autorelease
當然,現在當我們擁有時,我們ARC不需要考慮適當的物件保留和釋放。在ARC第一個代碼片段中可以正常作業而不會崩潰,第二個代碼片段可以在沒有記憶體泄漏的情況下正常作業。
所以現在只是為了程式員的感覺,他最喜歡哪一個。就像 swift 一樣:你可以寫:SomeClass(...)或SomeClass.init(...)
uj5u.com熱心網友回復:
第一個是類工廠方法。見http://www.apeth.com/iOSBook/ch04.html#_class_methods_2
第二個是真正的初始化程式。
在手動記憶體管理的時代,它們之間的區別更加明顯。既然 ARC 存在,它們就無法區分了——這就是 Swift 消除前者的原因。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/358538.html
