转载请标明出处: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对象呢?这些问题见后文描述。