很多人在初學移動開發的時候會對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中算是右值)。