Какие способы правильно использовать при использовании @synthesize - PullRequest
1 голос
/ 03 мая 2011

Я немного растерялся, когда речь заходит о синтезе свойств.

Допустим, у меня есть это свойство в моем файле * .h.

@property (nonatomic, retain) NSString *aString;

И в моем * .m файле я его синтезирую. @synthesize aString;

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

А когда я дам aString значение, какие пути верны?

self.aString = @"My New String"; // This will use the setter?
aString = @"My new String"; //This will not use the setter and retain the string, right?
aString = [@"My new string" retain]; //This will not use the setter, but it will retain the string ?
[self setAString:@"My new string"]; //This will also use the setter?

Заранее спасибо!

Ответы [ 4 ]

5 голосов
/ 03 мая 2011

Когда вы делаете:

@property (nonatomic, retain) NSString *aString;

... а затем:

@synthesize aString;

... ваш класс получает три основных вещи:

  1. Переменная-экземпляр с именем aString, на которую вы можете ссылаться непосредственно в вашем классе.
  2. Функция получения с сигнатурой - (NSString*) aString;, которая возвращает переменную экземпляра.
  3. Функция установки с сигнатурой - (void) setAString: (NSString*) value;, которая сохраняет передаваемый параметр и присваивает его переменной экземпляра (и освобождает любое ранее сохраненное значение, если оно существует);

С точки зрения реализации эти сгенерированные методы и поля могут выглядеть следующим образом:

//in the .h file
@interface MyClass {
    NSString* aString;
}

- (NSString*) aString;
- (void) setAString: (NSString*) value;

@end


//in the .m file
@implementation MyClass

- (NSString*) aString {
    return aString;
}

- (void) setAString: (NSString*) value {
    if (aString != value) {
        [aString release];
        aString = [value retain];
    }
}

@end

Итак, чтобы ответить на остальные ваши вопросы:

self.aString = @"My New String"; // This will use the setter?  Yes, and it will retain the string.
aString = @"My new String"; //This will not use the setter and retain the string, right?  Right.
aString = [@"My new string" retain]; //This will not use the setter, but it will retain the string?  Right again.
[self setAString:@"My new string"]; //This will also use the setter?  Yep.

Что касается того, что является правильным, все они, в зависимости от того, что вы хотите, и предполагают, что вы понимаете, как поведение отличается при использовании каждого из них, особенно в отношении освобождения / сохранения значений свойств. Например, этот код будет пропускать память:

self.aString = @"Value 1";  //go through the setter, which retains the string
aString = @"Value 2";        //bypass the setter, the 'Value 1' string will not be released

... и этот эквивалентный код не будет:

self.aString = @"Value 1";  //go through the setter, which retains the string
self.aString = @"Value 2";  //go through the setter again to release the first string
2 голосов
/ 03 мая 2011

Получатель и установщик используются, когда вы используете "точечный" синтаксис (например, self.aString, self.aString = ...) или синтаксис сообщения (например, [self aString], [self setAString:...]).

Присвоение непосредственно резервной переменной (в вашем случае несколько смущающе названной aString) не будет использовать синтезированные методы. Чтобы изменить имя вашей вспомогательной переменной, объявите его в своем интерфейсе как личную переменную (в .h):

NSString *aString_;

, а затем синтезировать его так:

@synthesize aString = aString_;

При этом будет использоваться aString_ в качестве вспомогательной переменной для вашего свойства, поэтому вы можете напрямую ссылаться на хранилище для вашего свойства, используя aString_.

0 голосов
/ 03 мая 2011

Ниже указаны правильные настройки.

self.aString = @"My New String";
[self setAString:@"My new string"];
0 голосов
/ 03 мая 2011

Относительно того, как будет выглядеть код, взгляните на этот вопрос .

Относительно того, какие из этих линий используют геттеры / сеттеры: только 1-й и 4-й делают.

self.aString = @"My New String";
[self setAString:@"My new string"];
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...