轉載請標明出處:blog.csdn.net/zhangxingping
關於屬性
在C++中,通常需要編寫Getter和Setter方法來擷取或者是設定執行個體變數的值。這兩種方法需要在程式中顯示的完成。這種方式在Objective-C中也是適用的。但是Objective-C提供了一種更為便捷的方式來完成這種功能。它就是屬性。和C++中的顯示的Getter和Setter方法相比,屬性機制使得Getter函數和Setter來的更容易和更簡化。
Objectivc-C中的屬性是通過關鍵字@property來聲明的。
例如,有類如下:
Student.h檔案:
#import <Foundation/Foundation.h> @interface Student : NSObject{@private NSString * name; //學生的姓名 float math; //數學科目的成績 float english; //英語科目的成績 } -(id)initWithName:(NSString*)aName math:(float)scoreMath english:(float)scoreEnglish; -(NSString *)getName;-(float)getMath;-(float)getEnglish; @end
Student.m檔案:
#import "Student.h" @implementation Student - (id)init{ self = [super init]; if (self) { name = nil; math = 0; english = 0; } return self;} -(id)initWithName:(NSString*)aName math:(float)scoreMath english:(float)scoreEnglish{ self = [super init]; if (self) { name = aName; math = scoreMath; english = scoreEnglish; } return self;} -(NSString *)getName{ return name;} -(float)getMath{ return math;} -(float)getEnglish{ return english;} - (void)dealloc{ [super dealloc];} @end
main.m檔案如下:
#import <Foundation/Foundation.h>
#import "Student.h" int main (int argc, const char * argv[]){ NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; Student * p = [[Student alloc] initWithName:@"Mark" math:80.0f english:100.00f]; NSLog(@"Name:%@",[p getName]); NSLog(@"Math:%f",[p getMath]); NSLog(@"Math:%f",[p getEnglish]); [p release]; [pool drain]; return 0;}
上面程式的輸出結果如下:
Name:Mark
Math:80.000000
Math:100.000000
上面的程式是通過C++中的方式來編寫Getter方法來擷取私人的執行個體變數的值。這些個Getter方法實現雖然簡單,但是必需有程式員顯示書寫來完成。應用屬性機制後,程式如下:
Student.h檔案:
#import <Foundation/Foundation.h> @interface Student : NSObject{@private NSString * name; //學生的姓名 float math; //數學科目的成績 float english; //英語科目的成績 } @property NSString * name;@property float math;@property float english; -(id)initWithName:(NSString*)aName math:(float)scoreMath english:(float)scoreEnglish; //-(NSString *)getName;//-(float)getMath;//-(float)getEnglish; @end
Student.m檔案:
#import "Student.h"@implementation Student @synthesize name;@synthesize math;@synthesize english; - (id)init{ self = [super init]; if (self) { name = nil; math = 0; english = 0; } return self;} -(id)initWithName:(NSString*)aName math:(float)scoreMath english:(float)scoreEnglish{ self = [super init]; if (self) { name = aName; math = scoreMath; english = scoreEnglish; } return self;} //-(NSString *)getName//{// return name;//}////-(float)getMath//{// return math;//}////-(float)getEnglish//{// return english;//}////- (void)dealloc//{// [super dealloc];//} @end
main.m檔案如下:
#import <Foundation/Foundation.h>#import "Student.h" int main (int argc, const char * argv[]){ NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; Student * p = [[Student alloc] initWithName:@"Mark" math:80.0f english:100.00f]; // NSLog(@"Name:%@",[p getName]);// NSLog(@"Math:%f",[p getMath]);// NSLog(@"Math:%f",[p getEnglish]); NSLog(@"Name:%@",p.name); NSLog(@"Math:%f",p.math); NSLog(@"Math:%f",p.english); [p release]; [pool drain]; return 0;}
程式的輸出如下:
Name:Mark
Math:80.000000
Math:100.000000
可見屬性機制使得程式更加簡潔明了。
上面程式中引入了新的關鍵字@synthesize,這個關鍵字告訴編譯器自動為其後面的屬性產生Getter()和Setter()方法。需要注意的一點是雖然在描述上適用的是“自動產生Getter()和Setter()方法”,但是實際上我們並看不到產生的對應代碼。需要明確的是編譯器自動產生的Getter方法:name(),math(),english()以及Sette方法:setName(), setMath(), setEnglish()的調用完全和普通的方法是一樣的。例如我們可以修改上面的main()函數如下:
#import <Foundation/Foundation.h>#import "Student.h" int main (int argc, const char * argv[]){ NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; Student * p = [[Student alloc] initWithName:@"Mark" math:80.0f english:100.00f]; // NSLog(@"Name:%@",[p getName]);// NSLog(@"Math:%f",[p getMath]);// NSLog(@"Math:%f",[p getEnglish]); // NSLog(@"Name:%@",p.name);// NSLog(@"Math:%f",p.math);// NSLog(@"Math:%f",p.english); [p setName:@"Tony"]; [p setMath:99.0f]; [p setEnglish:89.98f]; NSLog(@"Name:%@",[p name]); NSLog(@"Math:%f",[p math]); NSLog(@"Math:%f",[p english]); [p release]; [pool drain]; return 0;}
程式輸出為:
Name:Tony
Math:99.000000
Math:89.980003
上面的程式在Xcode中編譯後,會在@property NSString * name;代碼的所在行頭看到一個黃色的歎號,這表明編譯器在該行代碼處給出了編譯警告。單擊該黃色歎號可以看到給出的警告資訊:“No 'assign', 'retain', or 'copy' attribute is specified - 'assign' is assumed”和“Default property attribute 'assign' not appropriate for non-gc object”。警告資訊的意思是:“沒有明確指出應該是assign還是retain或者是copy,卻省的是assign”和“預設得屬性設定assign不適合非gc對象
”,那麼這兩個警告資訊的含義具體是什麼呢?assign,retian,copy又分別代表什麼含義呢?什麼是gc對象呢?什麼是非gc對象呢?這些問題見後文描述。