使用@synthesize时如何提供访问者方法的其他自定义实现?

时间:2009-08-20 15:18:43

标签: objective-c cocoa-touch cocoa accessor

我想在访问和更改属性时触发一些代码。我在我的代码中使用@property@synthesize作为我的ivars。这些属性被保留,所以我想保留@synthesize自动生成的内存管理内容。

但是,我假设@synthesize告诉编译器在@synthesize is的位置生成访问器方法代码,所以代码顶部的大多数情况都是对的吗?

当我有一个属性foo时,我会获得-setFoo-foo方法。我是否可以制作这样的方法,在更改属性时执行更多自定义代码?

-(void)setFoo {
    // custom stuff
}

现在这是一个问题。如何执行第一个?我不想在这里有一个不同的名字。有没有办法让@synthesize指令为getter和setter方法创建其他名称,然后我可以轻松调用它们?然后我仍然可以使用点语法来访问它们吗?

4 个答案:

答案 0 :(得分:5)

您可以像往常一样使用@property@synthesize,但提供自定义设置器或获取器(或两者),而是使用它们。通常我会做这样的事情:

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

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

    //custom code here
}

当我使用set属性时,它将调用我的自定义方法。但是,get仍将被合成。

答案 1 :(得分:1)

如果您为setter或getter提供实现,它将使用它而不是生成的实现。实现编译器在你合成时为你生成的getter和setter的“保留”方面并不难,所以你可以自己编写你自己的getter和setter,然后继续使用它。

答案 2 :(得分:0)

一个古怪的解决方案是创建一个抽象超类,它可以为您提供正常的属性合成。 然后创建一个你将实际使用的具体子类,它只是实现和覆盖方法(相同的签名)并调用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);

这允许您利用自动生成的代码,并且仍然可以执行您想要对您的类执行的操作。抽象超类通常是许多事物的有用解决方案。

答案 3 :(得分:-2)

是的,在@property声明中,您可以指定getter和setter方法。

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

foosetFoo:方法中,请拨打[self privateGetFoo][self privateSetFoo:f],然后调用您的自定义代码。

对象还可以使用addObserver:forKeyPath:options:context:为自己设置观察者。

那就是说,我不认为其中任何一种都是非常干净的做事方式。最好像其他人建议的那样编写自己的getter / setter。