Сеттер для NSString, как это работает? - PullRequest
1 голос
/ 28 августа 2009

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

// MAIN
int main (int argc, const char * argv[]) {
    PlanetClass *newPlanet_01 = [[PlanetClass alloc] init];
    [newPlanet_01 setGeekName:@"StarWars"];
}

.

// CLASS
@interface PlanetClass : NSObject {
    NSString *geekName;
}

- (NSString*) geekName;
- (void) setGeekName:(NSString*)gName;
@end

.

// SETTER
- (void)setGeekName:(NSString *)gName {
    if (geekName != gName) {
        [geekName release];
        geekName = [gName copy];
    }
}

(A) ... При первом создании экземпляра PlanetClass "newPlanet_01" создается объект переменной экземпляра NSString или просто указатель на возможный будущий объект? Если это просто указатель, что я высвобождаю позже в установщике, так как это просто указатель, а не указатель на объект?

(B) ... В приведенном выше примере "gName" является указателем на объект NSString @ "StarWars"?

(C) ... Далее указатель geekName отличается от gName (т. Е. Если geekName еще не указывает на @ "StarWars")

(D) ... выпуск geekName, то, что выпускается при первом запуске кода, я понимаю, что geekName - это просто указатель, на который ничего не указывает. Или выпуск просто не выпускает ничего в первый раз?

(E) ... Наконец, geekName = [копия gName]; недавно выпущенному geekName теперь назначено указывать на копию gName, что происходит с исходным gName?

1 Ответ

2 голосов
/ 28 августа 2009
  1. Вы создаете указатель, инициализированный на nil. Если вы знакомы с C или Java, то nil - это то же самое, что и NULL или null - это фактически указатель на ничто.
  2. Да. @"StarWars" называется "строковым литералом". Думайте о строковом литерале как о «постоянной» строке, которая хранится программой, а gName (в данном случае) является указателем на место в памяти этой строки.
  3. Да - эта строка гарантирует, что входящий gName не совпадает с переменной geekName объекта. Предположим, что проверки там не было, и gName и geekName указали на одну и ту же строку - тогда следующая строка освободит эту строку, что может сделать строку next недопустимой (это будет копирование выпущенная строка - очень плохо!).
  4. Если geekName все еще nil, то да, ничего не высвобождается; вернее, сообщение release отправляется объекту nil, который ничего не делает с сообщением. (В отличие от C или Java, в Objective-C вы можете отправлять сообщения на nil - но все такие сообщения игнорируются, а nil - это возвращаемое значение для всех таких сообщений).
  5. Вы создаете копию gName в случае, если gName является действительно экземпляром NSMutableString - вы не хотите, чтобы другой код изменял строку, которую вы рассматриваете как неизменную , Но что происходит с оригинальным объектом, на который указывает gName? Ну, это зависит от того, что звонящий делает с этим. Это могло быть выпущено, это могло быть сохранено, это могло быть передано другому объекту ... Вы действительно не знаете. В данном конкретном случае, поскольку gName указывает на строковый литерал "StarWars", с этим объектом ничего не происходит (поскольку это строковый литерал - см. Выше). И сам указатель действителен только в области действия этого метода и исчезает, как только метод возвращается.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...