Как обеспечить дополнительную реализацию методов доступа при использовании @synthesize?

StackOverflow https://stackoverflow.com/questions/1306897

Вопрос

Я хочу запускать некоторый код при доступе и изменении свойства.я использую @property и @synthesize в моем коде для моих иваров.Свойства сохраняются, поэтому я бы хотел, чтобы данные по управлению памятью автоматически создавались @synthesize.

Однако я предполагаю, что @synthesize сообщает компилятору сгенерировать код методов доступа прямо там, где @synthesize is, то есть большинство случаев находится в верхней части кода, верно?

И когда у меня есть недвижимость foo, Я получил -setFoo и -foo методы.Могу ли я тогда просто создать такой метод, чтобы выполнять еще один собственный код при изменении свойства?

-(void)setFoo {
    // custom stuff
}

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

Это было полезно?

Решение

Вы можете использовать @property и @synthesize как обычно, но предоставьте собственный установщик или геттер (или оба), и они будут использоваться вместо этого.Обычно я делаю что-то вроде этого:

// Override the setter
- (void)setName:(NSString *)aName
{
    if (name == aName)
        return;

    [name release];
    name = [aName retain];

    //custom code here
}

Когда я использую свойство set, оно вызывает мой собственный метод.Однако гет все равно будет синтезирован.

Другие советы

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

Одним из дурацких решений является создание абстрактного суперкласса, который дает вам обычный синтез свойств.Затем создайте конкретный подкласс, который вы действительно будете использовать, и который просто реализует и переопределяет метод (та же сигнатура) и вызывает super для выполнения фактической настройки.Это позволяет вам делать все, что вы хотите, до или после вызова реализации super.

Пример:

@interface ALTOClassA : NSObject


@property NSString *catName;

@end

Для этого теста в файле .m больше ничего не требуется, кроме файла-заглушки.

Создайте подкласс, ничего особенного в @interface не требуется.

#import "ALTOClassA.h"

@interface ALTOClassAJunior : ALTOClassA

@end

В @implementation мы выполняем переопределение.

#import "ALTOClassAJunior.h"

@implementation ALTOClassAJunior


- (void)setCatName:(NSString*)aCatName {
    NSLog(@"%@",NSStringFromSelector(_cmd));
    [super setCatName:aCatName];
    NSLog(@"after super: self.catName %@", self.catName);
}
@end

В использовании:

    ALTOClassAJunior *aCAJ = [ALTOClassAJunior new];
NSLog(@"aCAS.catName %@", aCAJ.catName);

NSLog(@"set it to George.");

[aCAJ setCatName:@"George"];

NSLog(@"aCAS.catName %@", aCAJ.catName);

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

Да, в объявлении @property вы можете указать методы получения и установки.

@property (readwrite,getter=privateGetFoo,setter=privateSetFoo:) NSObject * foo;

В вашей foo и setFoo: методы, позвоните [self privateGetFoo] или [self privateSetFoo:f] затем ваш собственный код.

Объект также может установить наблюдателя на себя с помощью addObserver:forKeyPath:options:context:.

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top