很多人在初学移动开发的时候会对object-c中的合成存取方法感到疑惑,此处尝试为看到本文有缘人答疑解惑,鄙人才疏学浅,难免有疏漏谬误之处,热烈欢迎诸位看官拍砖指点.
1.合成存取方法:
OC为增加开发效率,从2.0之后不需要程序员自己来写成员变量的setter和getter方法,取而代之的是自动合成的setter和getter。
系统自动合成setter和getter需要2步:
- 在类interface部分用@propert指令定义属性。
- 在实现部分用@synthesize指令声明属性。
属性的定义:如果为某个类定义了一个成员变量并提供了相应地setter、getter方法,那么可称为定义了一个属性(property)。
使用@synthesize的语法格式如下:
@synthesize 属性名 [=成员变量名];
如果@synthesize后没有属性,如果没有指定成员变量名,成员变量默认与合成的getter方法同名。 这里需要注意的是,此行为可能导致莫名其妙的错误,请看代码:
//接口部分#import <Foundation/Foundation.h> @interface setGet : NSObject @property (setter=setAge:) int age; @property NSString *name; @end
//实现部分#import "setGet.h" @implementation setGet @synthesize age,name; - (void) setAge:(int)age { NSLog(@"Call setter method!"); self.age=age; } @end
//主程序部分#import <Foundation/Foundation.h> #import "setGet.h" int main(int argc, const char * argv[]) { @autoreleasepool { setGet* test=[[setGet alloc] init]; test.age=80; NSLog(@"The age is:%d",test.age); } return 0; }
在以上测试代码中,将会无限输出:Call setter method!
具体原因不言自明,正因为没有在@synthesize部分对属性名指定成员变量名,导致了程序产生了递归。
只要在实现部分稍作改动,程序便正常输出:
//实现部分修改 #import "setGet.h" @implementation setGet @synthesize age=whatever,name; - (void) setAge:(int)age { NSLog(@"Call setter method!"); self->whatever=age; // or :whatever=age; } @end
不过OC规范一般是下划线开头来定义成员变量:_age。
补充一句:
“.”的用法仅限于getter和setter方法,用于左值则调用setter方法,用于右值则调用getter方法(如主程序中的NSLog中算是右值)。
时间: 2024-10-23 08:20:45