转载请标明出处:blog.csdn.net/zhangxingping
在C++中,通常需要编写Getter和Setter方法来获取或者是设置实例变量的值。这两种方法需要在程序中显示的完成。这种方式在Objective-C中也是适用的。但是Objective-C提供了一种更为便捷的方式来完成这种功能。它就是属性。和C++中的显示的Getter和Setter方法相比,属性机制使得Getter函数和Setter来的更容易和更简化。
Objectivc-C中的属性是通过关键字@property来声明的。
例如,有类如下:
Student.h文件:
#import
@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
#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
@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
#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
#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对象呢?这些问题见后文描述。