Chr*_*ter 4 setter objective-c infinite-loop
我在Objective-C中偶然发现了一些奇怪的行为.我有一个main.m:
#include <Foundation/Foundation.h>
#include "AClass.h"
int main(int argc, char* argv[]) {
AClass* tmpClass = [[AClass alloc] init];
[tmpClass setAVariable:12];
return -1;
}
Run Code Online (Sandbox Code Playgroud)
标题AClass.h:
#include <Foundation/Foundation.h>
@interface AClass: NSObject;
-(void) setAVariable:(int) bVariable;
@property int aVariable;
@end
Run Code Online (Sandbox Code Playgroud)
和相应的实现文件AClass.m:
#include <Foundation/Foundation.h>
#include <AClass.h>
@implementation AClass
@dynamic aVariable;
int aVariable;
-(void) setAVariable:(int)bVariable {
NSLog(@"foo:");
self.aVariable = bVariable;
}
@end
Run Code Online (Sandbox Code Playgroud)
在Linux上使用clang或在OSX上使用Xcode编译此代码时,setAVariable:会触发无限递归.我想知道这是否是clang/Objective-C中的错误.
这是预料之中的.您正在访问setter中的setter.
self.aVariable = bVariable实际上是在调用[self setAVariable:bVariable],因此是递归.点语法就是这样,一种特殊的语法,实际上只是实际setter方法的简写.在编写自己的setter方法时,应该访问支持实例变量,而不是属性本身.例如
- (void) setAVariable:(int)bVariable {
NSLog(@"foo:");
aVariable = bVariable;
}
Run Code Online (Sandbox Code Playgroud)
通常的做法是为实例变量使用前导下划线,以便在您直接访问实例变量与属性(通过getter和setter来获取后备实例变量)时很容易识别.
此外,最佳做法是使用#import而不是#include,因为#import只包含一次文件,即使同一文件有多个#import语句,可能会加快编译时间.
| 归档时间: |
|
| 查看次数: |
680 次 |
| 最近记录: |