轉載請标明出處: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對象呢?這些問題見後文描述。