自定义Getter和Setter iOS 5

ale*_*lex 33 objective-c getter-setter ios automatic-ref-counting

我想使用ARC覆盖我的ObjC类中的getter和setter.

.h文件

@property (retain, nonatomic) Season *season;
Run Code Online (Sandbox Code Playgroud)

.m文件

@synthesize season;


- (void)setSeason:(Season *)s {
    self.season = s; 

    // do some more stuff
}

- (Season *)season {
    return self.season;
}
Run Code Online (Sandbox Code Playgroud)

我在这里错过了什么吗?

jle*_*ehr 88

是的,那些是无限的递归循环.那是因为

self.season = s;
Run Code Online (Sandbox Code Playgroud)

由编译器翻译成

[self setSeason:s];
Run Code Online (Sandbox Code Playgroud)

return self.season;
Run Code Online (Sandbox Code Playgroud)

被翻译成

return [self season];
Run Code Online (Sandbox Code Playgroud)

摆脱点访问器 self.,你的代码将是正确的.

但是,这种语法可能会令人困惑,因为您的属性season和变量season共享相同的名称(尽管Xcode会通过不同地着色这些实体来减少混淆).可以通过编写显式更改变量名称

@synthesize season = _season;
Run Code Online (Sandbox Code Playgroud)

或者,更好的是,@synthesize完全省略该指令.现代的Objective-C编译器将自动为您合成访问器方法和实例变量.

  • 在Xcode 5中,如果同时提供自定义getter和setter,则系统不再合成成员变量.您必须使用@synthesize来执行此操作.根据您的建议,它不再是可选的. (5认同)

Jer*_*emy 16

如果您要实现自己的getter和setter,则需要维护一个内部变量:

@synthesize season = _season;

- (void)setSeason:(Season *)s {
    // set _season
    //Note, if you want to retain (as opposed to assign or copy), it should look someting like this
    //[_season release];
    //_season = [s retain];
}

- (Season *)season {
    // return _season
}
Run Code Online (Sandbox Code Playgroud)


Noa*_*oon 5

你失踪的事情是,Objective-C的编译器基本上变成了self.foo = bar语法进入[self setFoo:bar],并self.foo进入[self foo].您目前实施的方法正在调用自己的方法.正如Jeremy建议的那样,你需要实现它们,以便setter实际上将它所调用的值赋给类上的实例变量,并且getter返回该实例变量的值.