Требуется некоторое понимание одноэлементного шаблона

#iphone #objective-c #ios #cocoa

#iPhone #цель-c #iOS #cocoa #objective-c

Вопрос:

Я собираюсь вставить сюда код, и у меня возник вопрос относительно того, что я хотел просто понять, основываясь на логическом подходе.

 @interface MySingleton : NSObject {
NSString *enteredCode; 
}

@property (nonatomic, retain) NSString *enteredCode;

@end


@synthesize enteredCode;

-(void) addInput:(NSString *) input
{ 
self.enteredCode = [self.enteredCode stringByAppendingString:input];
}

- (void)dealloc {
[enteredCode release];
}

@end
  

В моем коде, если я использую «self.enteredCode = [self.enteredCode stringByAppendingString:input];»

все работает нормально, но «Введенный код = [self.enteredCode stringByAppendingString:input];» он получает exc_bad_access, и мне просто интересно, почему это так?

Я просто пытаюсь понять, какая разница на самом деле, если там нет «я»?

Спасибо.

Комментарии:

1. Второстепенный момент, не связанный с вашим вопросом: NSString свойства должны быть объявлены как copy не retain .

Ответ №1:

Это не имеет отношения к одиночным элементам. Когда вы это делаете self.enteredCode , вы проходите через свойство, для которого установлено значение «сохранить». stringByAppendingString Метод — это удобный метод, который возвращает вам автоматически выпущенный объект, что означает, что он будет выпущен в какой-то момент в следующем цикле выполнения. Вам необходимо сохранить это значение, чтобы оно не было выпущено, что нормально, если вы назначаете его через свойство, поскольку оно правильно сохраняется вами, и вы можете использовать его по своему усмотрению.

Когда вы ссылаетесь на переменную directory (без self. ), вы обходите это, и, таким образом, вы никогда не сохраняете значение, значение впоследствии освобождается, и вы ссылаетесь на плохую память и ОООООООООООМ, плохой доступ.

Комментарии:

1. Дальнейшее уточнение: всегда помните, что self.foo = bar это то же самое, что [self setFoo:bar] .

Ответ №2:

при вызове self.enteredCode = XXX он вызовет [self setEnteredCode:XXX] . Поскольку вы используете свойство сохранения, это освободит старое значение введенного кода и сохранит новое значение.

если вы напрямую манипулируете переменной enteredCode, у вас будут сбои в памяти и сбои, потому что он попытается освободить что-то, что не будет сохранено позже.

Ответ №3:

Если я правильно понимаю, self.Введенный код работает, но введенный код не выполняется.

Если это так, то я считаю, что это потому, что вы обходите свойство и устанавливаете iVar напрямую. Это означает, что вам назначен объект автоматического освобождения в обход механизма сохранения.

Подумайте о том, чтобы использовать что-то вроде _enteredCode для ваших iVars, чтобы в вашем коде было понятнее, когда вы обходите свойства.

Комментарии:

1. брайан мак, в моем случае на самом деле я не хочу обходить свойство и скорее сохраняю самую свежую информацию, для которой self.enteredCode будет иметь смысл. Спасибо.