2012-06-19 27 views
5

我寫了下面的示例代碼,看看ARC如何工作爲什麼弱的NSString屬性不能在iOS中發佈?

@property (nonatomic, weak) NSString *myString; 
@property (nonatomic, weak) NSObject *myObj; 
@end 

@implementation ViewController 
@synthesize myString = _myString; 
@synthesize myObj = _myObj; 
- (void) viewDidAppear:(BOOL)animated 
{ 
    NSLog(@"Appearing Obj: !%@!",self.myObj); 
    NSLog(@"Appearing String: !%@!",self.myString); 
} 

- (void)viewDidLoad 
{ 
    self.myObj = [[NSObject alloc] init]; 
    self.myString = [[NSString alloc] init]; 
    NSLog(@"Loading Obj %@",self.myObj); 
    NSLog(@"Loading String: !%@!",self.myString); 
} 

然而令人驚訝的我得到這些結果:

2012-06-19 15:08:22.516 TESTER[4041:f803] Loading Obj (null) 
2012-06-19 15:08:22.517 TESTER[4041:f803] Loading String: !! 
2012-06-19 15:08:22.533 TESTER[4041:f803] Appearing Obj: !(null)! 
2012-06-19 15:08:22.535 TESTER[4041:f803] Appearing String: !! 

正如你所看到的,OBJ得到釋放正常,但我的字符串(這也是一個弱財產)不打印出null ...爲什麼不呢?

+0

是你在'myString'中設置的字符串是否通過改變字符串文字(類似於@「Hello world!」)? –

回答

12

NSString使用各種內部欺騙來重複使用對象並避免不必要的分配和副本。它可以這樣做,因爲NSString實例是不可變的。在這種情況下,可能有一個共享實例來表示由[[NSString alloc] init]返回的空字符串,並且此共享實例將作爲單例保留在別處。

+0

這似乎是有道理的。謝謝! – Nosrettap

+0

也許有人可以查看NSString源代碼來確認這一點。 –

+0

有意義,但我不認爲依靠這種行爲是明智的,這似乎只是某種優化的一種表現,在未來某個日期可能會發生變化。 – Rob

6

[[NSString alloc] init]總是返回相同值。你可以自己檢查一下。

NSString *string1 = [[NSString alloc] init]; 
NSString *string2 = [[NSString alloc] init]; 
NSString *string3 = [[NSString alloc] init]; 
NSLog(@"string1 = %p, string2 = %p, string3 = %p", string1, string2, string3) 

該代碼返回三個相同的地址。在我的情況下,產量爲:

string1 = 0x3e8dd74c, string2 = 0x3e8dd74c, string3 = 0x3e8dd74c 

這意味着[[NSString alloc] init]回報辛格爾頓。單身通常不能被釋放。

用其它方法制作的字符串(如initWithFormat:)使通常的「非單」的目的,其通常可以釋放,但有一些例外。

另外: 尋找源代碼(彙編):

-[NSPlaceholderString init]: 
00040ea4  f64b009c  movw r0, 0xb89c 
00040ea8  f2c00016  movt r0, 0x16 
00040eac   4478  add  r0, pc 
00040eae   4770  bx  lr 

它會是這樣的(在的ObjectiveC)

-(id)init 
{ 
    return SOME_CONSTANT_VALUE; 
} 

這可能是kCFEmptyString,但我不當然。

相關問題