Почему это свойство нужно «сохранить»? - PullRequest
5 голосов
/ 18 мая 2009

Учитывая следующее определение класса с сохранением свойств:

@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 требует "retain":

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

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

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

1 Ответ

16 голосов
/ 18 мая 2009

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

Когда вы установите:

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...