2010-01-31 5 views
1

У меня вопрос о том, как работают переменные экземпляра и когда использовать @property. Вот пример файла интерфейса, который я работаю сВопрос о ivars и @ property на iPhone

@interface PackageModel : NSObject { 
    NSString *tracking; 
    NSString *carrier; 
    NSString *status; 
    NSMutableDictionary *events; 

    // Connection ivars 
    NSMutableData *receivedData; 

    // Parsing ivars 
    int tagLevel; 
    NSMutableArray *tagTree; 
    NSString *parentTag; 
    NSString *currentTag; 
} 

@property (nonatomic, retain) NSMutableData *receivedData; 

- (id)initWithTrackingString:(NSString *)string; 
- (void)getPackageDataWithEvents; 
- (void)printMe; 

@end 

Как получить доступ к ним в коде файла. Могу ли я получить доступ к трекинг, носитель и статус в методах этого класса, просто используя что-то вроде

tracking = [[NSString alloc] initWithString:@"Hello World"]; 

Кроме того, что нужно положить в dealloc переменные? Только переменные, которые я имею в @ свойстве/@ синтезируют? Или мне нужно освободить все переменные экземпляра в методе dealloc.

Я просто ищу некоторые разъяснения о том, как переменные экземпляра работают в Objective-C. Благодарю.

ответ

3

@property объявления - это не что иное, как генерируемые компилятором методы получения и сеттера. Вот и все. Просто методы. Очевидно, вы должны получать и устанавливать что-то, поэтому мы создаем ivar, который идет вместе с геттерами и сеттерами. В нашем примере выше, ваш компилятор генерирует:

- (NSMutableData *) receivedData; 
- (void) setReceivedData:(NSMutableData *)newReceivedData; 

Поглотитель возвращает значение в переменной receivedData экземпляра, и связующий изменяет значение в переменной receivedData экземпляра.

(Примечание стороны: с 64-разрядной среды выполнения, вы можете пропустить объявить переменную экземпляра, но я все же хотел бы поставить его в только, чтобы быть явным)

Как за то, что вы должны сделать в вашем методе dealloc , вам нужно освободить переменные экземпляра, которые были retain ed или copy ed. Поэтому в вашем примере вам нужно будет сделать [receivedData release]; в вашем методе dealloc, потому что когда вы устанавливаете ivar receivedData, вы сохранили новое значение (это то, что означает retain на линии @property). Если вы не укажете retain или copy в объявлении @property, то по умолчанию он равен assign, и вам не нужно ничего делать. Помимо этого, вам нужно будет освободить любые другие переменные экземпляра, которые вы сохранили самостоятельно (т. Е. Не с помощью установщика).

Для вашего последнего вопроса, да, вы можете просто сделать:

tracking = [[NSString alloc] initWithFormat:@"Hello, %@!", @"world"]; 

Внутри вашего собственного класса, у вас есть прямой доступ ко всем вашим собственным переменным экземпляра (и любые защищенные и открытые Ивар ваших супер классов).

+0

Теперь, для currentTag и parentTag, которые я определил там, я установлю их в методах делегатов NSXMLParser по currentTag = qName. Мне не нужно выпускать их в dealloc, потому что они просто указывают на эти другие строки, правильно? Но, если бы я сделал их @property, мне нужно было бы отпустить их правильно? – rickharrison

+0

rickharrison: '@ property' не имеет никакого отношения к тому, принадлежит ли вам объект. Не имеет значения, как вы пришли к нему; если вы владеете им, вы должны его освободить. См. Правила управления памятью: http://developer.apple.com/mac/library/documentation/General/Conceptual/DevPedia-CocoaCore/MemoryManagement.html –

0

Одним из преимуществ использования свойства @/syntehsize является то, что он подталкивает вас к использованию методов доступа для иваров. Это поможет вам лучше управлять памятью. На iPhone вы должны знать о том, чтобы сохранить счет по двум причинам: 1. Не используйте память. 2. Избегайте сбоев. Когда вы напрямую обращаетесь к ivars, вы рискуете забыть сохранить переменную, а затем перейти к ней позже, чтобы узнать, что она была освобождена. Или наоборот, вы забыли выпустить переменную, и довольно скоро вы накопили столько памяти, что iPhone OS сообщает вашему приложению прекратить действие.

Использование методов доступа, даже внутри класса, как правило, является хорошей идеей. Единственное место, где я обычно устанавливаю ivars напрямую, находится внутри метода init класса. Я также вообще выпускаю все свои ivars внутри метода dealloc.

1

Yikes, это очень широкий вопрос. Я настоятельно рекомендую вам прочитать статьи Objective-C Primer от Apple и их full reference to the language.

В качестве стартера вы спрашиваете: «Как я могу получить к ним доступ в коде файла?» Вы не укажете, какой файл. Внутри @implementation из PackageModel вы можете просто обратиться к переменным экземпляра, как в примере отслеживания. Вы не можете легко получить к ним доступ из других классов.

Если вы сделаете их @properties и @synthesize их, вы можете получить к ним доступ в пределах класса, такого как self.tracking. Более того, теперь вы также можете получить доступ к ним и из других классов.

PackageModel *model = [[PackageModel alloc] init]; 
model.receivedData = [NSMutableData data]; 

Еще одно преимущество свойств заключается в том, что они могут обрабатывать управление памятью для вас. Когда все сделано правильно, вам действительно не нужно беспокоиться о сохранении и выпуске. Это свойство receivedData вашего класса PackageModel автоматически освободит любые ранее сохраненные объекты перед назначением новых данных. Это великолепно. Это происходит потому, что компилятор автоматически «синтезирует» сеттеры и геттеры, а затем вызывает их для доступа через оператор точки.

В заключение отметим, что эти сеттеры и геттеры автоматически защищены блоком @synchronize, который гарантирует, что операции происходят атомарно (и что вторая нить не может нарушить действие на полпути). Это в значительной степени ненужно на iPhone и вызывает приличное количество накладных расходов, поэтому вам нужно объявить все свои свойства как nonatomic в дополнение к вашим разрешениям на чтение и запись и схему управления памятью.

1

Что-то не охватывается в том, что ваша последняя строка кода может быть:

tracking = @"Hello World"; 

«@» в основном создает объект строки для вас.

Смежные вопросы