6

我想在访问和更改属性时触发一些代码。我在我的 ivars 代码中使用@property和。@synthesize属性被保留,所以我想保留由@synthesize.

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

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

-(void)setFoo {
    // custom stuff
}

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

4

4 回答 4

5

你可以像往常一样使用@propertyand @synthesize,但提供一个自定义的 setter 或 getter(或两者),而这些将被使用。通常我会做这样的事情:

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

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

    //custom code here
}

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

于 2009-08-20T15:29:17.747 回答
1

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

于 2009-08-20T15:22:23.720 回答
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);

这允许您利用自动生成的代码,并且仍然可以对您的课程做您想做的事情。抽象超类通常是许多事情的有用解决方案。

于 2013-09-06T00:54:07.153 回答
-2

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

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

在您的fooandsetFoo:方法中,调用[self privateGetFoo][self privateSetFoo:f]然后调用您的自定义代码。

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

也就是说,我认为这两种方式都不是非常干净的做事方式。最好按照其他人的建议编写自己的 getter/setter。

于 2009-08-20T15:27:45.037 回答