2009-05-18 2 views
5

Учитывая следующее определение класса с сохраняющими свойствами:Почему для этого свойства требуется «сохранить»?

@interface FeedEntry : NSObject<NSCoding> 
{ 
    NSURL* url; 
    NSData* source; 
} 

@property (retain) NSURL* url; 
@property (retain) NSData* source; 
@end 

@implementation FeedEntry 

@synthesize url; 
@synthesize source; 

-(void)encodeWithCoder:(NSCoder*)coder 
{ 
    [coder encodeObject:url  forKey:@"url"]; 
    [coder encodeObject:source forKey:@"source"]; 
} 

Почему свойство URL в методе initWithCoder нужен «сохранить»:

-(id)initWithCoder:(NSCoder*)coder 
{ 
    url = [[coder decodeObjectForKey:@"url"] retain]; 
    source = [coder decodeObjectForKey:@"source"]; 

    NSLog(@"got url=%@\n", url); 
    return self; 
} 

В частности, почему не синтезированный " get url "сохранить объект? (Я предполагаю, что исходное свойство также потребуется сохранить).

ответ

16

Быстрый ответ:

При установке:

url = [[coder decodeObjectForKey:@"url"] retain]; 

вы не с помощью @property. Вы вручную устанавливаете значение переменной экземпляра url. Поэтому вы также должны вручную указать значение retain.

Чтобы установить переменный, используя синтезируемые свойства, вы бы вместо того, чтобы позвонить:

[self setUrl:[coder decodeObjectForKey:@"url"]]; 

или

self.url = [coder decodeObjectForKey:@"url"]; 

Каждого из этих форм будет использовать синтезированные методы и обрабатывать retain автоматически ,

Детали:

В Objective-C, в @property и @synthesize ключевые слова автоматически создавать методы получения и установки для вас:

@interface MyClass 
{ 
    id someValue; 
} 
@property (retain) id someValue; 
@end 

@implementation MyClass 
@synthesize someValue; 
@end 

эквивалентно:

@interface MyClass 
{ 
    id someValue; 
} 
- (id)someValue; 
- (void)setSomeValue:(id)newValue; 
@end 

@implementation MyClass 
- (id)someValue { return someValue; } 
- (void)setSomeValue:(id)newValue 
{ 
    [newValue retain]; 
    [someValue release]; 
    someValue = newValue; 
} 
@end 

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

+0

Действительно! У меня такое чувство, что это будет укусить меня довольно часто. Спасибо за ваш ответ. – Justicle

+0

Мое удовольствие. Сначала нужно привыкнуть. После того, как вы это делаете какое-то время, это становится второй натурой :) –

+4

Это одна из причин, по которой мне нравится использовать префикс _ для частных переменных экземпляра, это очень легко понять, когда вы используете переменную экземпляра против всего остального. –

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