2010-04-01 1 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

ответ

1

Решение действительно связано с удержанием, как указано пользователем invariant. Метод класса:

output = [NSMutableString stringWithCapacity:0]; 

возвращает autorelease NSMutableString. Когда мне присвоено свойство вывода, похоже, даже с сохраненным флагом, он не сохранил его. Решение заключалось в том, чтобы распределить его самостоятельно, а не автореферат:

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

Затем удержание сработало. Любое объяснение, почему было бы очень желанным.

Редактировать

Разобрался почему. Я обращался к экземпляру vars напрямую, а не через getter/setter, который я синтезировал. Дополнительная информация о моих blog.

+0

Rufus от AppleDevForums дал мне довольно хороший ответ на подобную вещь: – Emil

+1

Это очень запутанно, и 7 или 8 вещей, которые вам нужно знать для этого, наконец, имеют смысл не в тех же местах. Прежде всего, верьте, что 'self.foo = bar;' - это то же самое, что (синтаксический ярлык для) '[self setFoo: bar];' А именно, 'вызывать метод 'setFoo: bar'' на меня (этот объект) ». Теперь вы спросите себя: «А? Я не писал никакого метода setFoo». Правда, вы этого не сделали. Директива @synthesize сообщила компилятору написать метод setFoo. – Emil

+0

И компилятор не предоставляет вам исходный код этого метода, который он написал для вас. Но что делает этот скрытый метод setFoo:? 1. Он проверяет, является ли «бар» уже установленным «foo». 2. Если нет, он отправляет сообщение «release» на «foo» 3. Он устанавливает указатель «foo» на «bar» указателя 4. Он отправляет сообщение «сохранить» в «foo» (ЕСЛИ Директива @property для «foo» сказала, чтобы это сделать). – Emil

2

Изменение линии

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

в

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

(или self.output = ..., если вы предпочитаете, чтобы нотации).

Хотя вы объявили свойство, вы не используете сеттер, поэтому вы не сохраняете строку.

+0

Действительно? Да, хорошо знать. Я думал, когда я @synthesize переменную, она делает это для меня. – typeoneerror