2010-04-01 140 views
6

一直在尋找這一點,而不理解爲什麼這個簡單的代碼會拋出一個錯誤。爲簡潔起見縮短:將字符串附加到NSMutableString

NSMutableString *output; 

... 

@property (nonatomic, retain) NSMutableString *output; 

... 

@synthesize output; 

... 

// logs "output start" as expected 
output = [NSMutableString stringWithCapacity:0]; 
[output appendString:@"output start"]; 
NSLog(@"%@", output); 

... 

// error happens here 
// this is later on in a different method 
[output appendString:@"doing roll for player"]; 

任何人都可以發現我的錯誤嗎?

+0

什麼是確切的錯誤? – outis 2010-04-01 06:09:15

回答

1

該解決方案實際上確實有做保留,用戶invariant所示。類方法:

output = [NSMutableString stringWithCapacity:0]; 

返回autorelease NSMutableString。當被分配到我的輸出屬性 - 表面上,即使有保留標誌 - 它並沒有保留它。解決方案是自己分配它,而不是autorelease:

output = [[NSMutableString alloc] initWithCapacity:0]; 

然後保留工作。任何解釋爲什麼會非常受歡迎。

編輯

想通了,爲什麼。我直接訪問實例變量,而不是通過我合成的getter/setter。有關我的blog的更多信息。

+0

魯弗斯給了我一個很好的答案,一個類似的事情: – Emil 2010-06-06 11:47:45

+1

這是非常混亂,你需要知道這最終使意義上的7米或8的東西是不是在同一個地方。首先,要相信'self.foo = bar;'與'[self setFoo:bar]'的語法快捷方式完全相同;'即',調用方法''setFoo:bar'「在我身上(這個對象)。「現在你會問自己,「嗯?我沒有寫任何」setFoo「方法。」誠然,你沒有。 @synthesize指令告訴編譯器編寫「setFoo」方法。 – Emil 2010-06-06 11:51:12

+0

而編譯器不會爲您提供它爲您寫的這種方法的源代碼。但是這個隱藏的「setFoo:」方法是做什麼的? 1.它檢查「bar」是否已經設置爲「foo」。 2.如果沒有,它發送「釋放」消息發送到「foo」的 3.它設置指針「foo」的指針「欄中的」 4.發送「保留」消息發送到「foo」的(IF的「foo」的@property指令表示這麼做)。 – Emil 2010-06-06 11:51:44

2

更改線路

output = [NSMutableString stringWithString:@"output start"]

[self setOutput:[NSMutableString stringWithString:@"output start"]]

(或self.output = ...如果你喜歡的符號)。

雖然你已經聲明的屬性,您使用的不是制定者,這樣你就不會保留的字符串。

+0

真的嗎?嗯,很高興知道。我認爲當我@合成一個變量時,它會爲我做這件事。從AppleDevForums – typeoneerror 2010-04-01 17:10:51