编程笔记(objective-c :关于属性)

关于属性

在C++中,通常需要编写Getter和Setter方法来获取或者是设置实例变量的值。这两种方法需要在程序中显示的完成。这种方式在Objective-C中也是适用的。但是Objective-C提供了一种更为便捷的方式来完成这种功能。它就是属性。和C++中的显示的Getter和Setter方法相比,属性机制使得Getter函数和Setter来的更容易和更简化。

Objectivc-C中的属性是通过关键字@property来声明的。

例如,有类如下:

Student.h文件:

  1. #import<Foundation/Foundation.h>
  2. @interfaceStudent:NSObject
  3. {
  4. @private
  5. NSString*name;//学生的姓名
  6. floatmath;//数学科目的成绩
  7. floatenglish;//英语科目的成绩
  8. }
  9. -(id)initWithName:(NSString*)aNamemath:(float)scoreMathenglish:(float)scoreEnglish;
  10. -(NSString*)getName;
  11. -(float)getMath;
  12. -(float)getEnglish;
  13. @end

Student.m文件:

  1. #import"Student.h"
  2. @implementationStudent
  3. -(id)init
  4. {
  5. self=[superinit];
  6. if(self)
  7. {
  8. name=nil;
  9. math=0;
  10. english=0;
  11. }
  12. returnself;
  13. }
  14. -(id)initWithName:(NSString*)aNamemath:(float)scoreMathenglish:(float)scoreEnglish
  15. {
  16. self=[superinit];
  17. if(self)
  18. {
  19. name=aName;
  20. math=scoreMath;
  21. english=scoreEnglish;
  22. }
  23. returnself;
  24. }
  25. -(NSString*)getName
  26. {
  27. returnname;
  28. }
  29. -(float)getMath
  30. {
  31. returnmath;
  32. }
  33. -(float)getEnglish
  34. {
  35. returnenglish;
  36. }
  37. -(void)dealloc
  38. {
  39. [superdealloc];
  40. }
  41. @end

main.m文件如下:

#import <Foundation/Foundation.h>

  1. #import"Student.h"
  2. intmain(intargc,constchar*argv[])
  3. {
  4. NSAutoreleasePool*pool=[[NSAutoreleasePoolalloc]init];
  5. Student*p=[[Studentalloc]initWithName:@"Mark"math:80.0fenglish:100.00f];
  6. NSLog(@"Name:%@",[pgetName]);
  7. NSLog(@"Math:%f",[pgetMath]);
  8. NSLog(@"Math:%f",[pgetEnglish]);
  9. [prelease];
  10. [pooldrain];
  11. return0;
  12. }

上面程序的输出结果如下:

Name:Mark

Math:80.000000

Math:100.000000

上面的程序是通过C++中的方式来编写Getter方法来获取私有的实例变量的值。这些个Getter方法实现虽然简单,但是必需有程序员显示书写来完成。应用属性机制后,程序如下:

Student.h文件:

  1. #import<Foundation/Foundation.h>
  2. @interfaceStudent:NSObject
  3. {
  4. @private
  5. NSString*name;//学生的姓名
  6. floatmath;//数学科目的成绩
  7. floatenglish;//英语科目的成绩
  8. }
  9. @propertyNSString*name;
  10. @propertyfloatmath;
  11. @propertyfloatenglish;
  12. -(id)initWithName:(NSString*)aNamemath:(float)scoreMathenglish:(float)scoreEnglish;
  13. //-(NSString*)getName;
  14. //-(float)getMath;
  15. //-(float)getEnglish;
  16. @end

Student.m文件:

  1. #import"Student.h"
  2. @implementationStudent
  3. @synthesizename;
  4. @synthesizemath;
  5. @synthesizeenglish;
  6. -(id)init
  7. {
  8. self=[superinit];
  9. if(self)
  10. {
  11. name=nil;
  12. math=0;
  13. english=0;
  14. }
  15. returnself;
  16. }
  17. -(id)initWithName:(NSString*)aNamemath:(float)scoreMathenglish:(float)scoreEnglish
  18. {
  19. self=[superinit];
  20. if(self)
  21. {
  22. name=aName;
  23. math=scoreMath;
  24. english=scoreEnglish;
  25. }
  26. returnself;
  27. }
  28. //-(NSString*)getName
  29. //{
  30. //returnname;
  31. //}
  32. //
  33. //-(float)getMath
  34. //{
  35. //returnmath;
  36. //}
  37. //
  38. //-(float)getEnglish
  39. //{
  40. //returnenglish;
  41. //}
  42. //
  43. //-(void)dealloc
  44. //{
  45. //[superdealloc];
  46. //}
  47. @end

main.m文件如下:

  1. #import<Foundation/Foundation.h>
  2. #import"Student.h"
  3. intmain(intargc,constchar*argv[])
  4. {
  5. NSAutoreleasePool*pool=[[NSAutoreleasePoolalloc]init];
  6. Student*p=[[Studentalloc]initWithName:@"Mark"math:80.0fenglish:100.00f];
  7. //NSLog(@"Name:%@",[pgetName]);
  8. //NSLog(@"Math:%f",[pgetMath]);
  9. //NSLog(@"Math:%f",[pgetEnglish]);
  10. NSLog(@"Name:%@",p.name);
  11. NSLog(@"Math:%f",p.math);
  12. NSLog(@"Math:%f",p.english);
  13. [prelease];
  14. [pooldrain];
  15. return0;
  16. }

程序的输出如下:

Name:Mark

Math:80.000000

Math:100.000000

可见属性机制使得程序更加简洁明了。

上面程序中引入了新的关键字@synthesize,这个关键字告诉编译器自动为其后面的属性生成Getter()和Setter()方法。需要注意的一点是虽然在描述上适用的是“自动生成Getter()和Setter()方法”,但是实际上我们并看不到生成的对应代码。需要明确的是编译器自动生成的Getter方法:name(),math(),english()以及Sette方法:setName(), setMath(), setEnglish()的调用完全和普通的方法是一样的。例如我们可以修改上面的main()函数如下:

  1. #import<Foundation/Foundation.h>
  2. #import"Student.h"
  3. intmain(intargc,constchar*argv[])
  4. {
  5. NSAutoreleasePool*pool=[[NSAutoreleasePoolalloc]init];
  6. Student*p=[[Studentalloc]initWithName:@"Mark"math:80.0fenglish:100.00f];
  7. //NSLog(@"Name:%@",[pgetName]);
  8. //NSLog(@"Math:%f",[pgetMath]);
  9. //NSLog(@"Math:%f",[pgetEnglish]);
  10. //NSLog(@"Name:%@",p.name);
  11. //NSLog(@"Math:%f",p.math);
  12. //NSLog(@"Math:%f",p.english);
  13. [psetName:@"Tony"];
  14. [psetMath:99.0f];
  15. [psetEnglish:89.98f];
  16. NSLog(@"Name:%@",[pname]);
  17. NSLog(@"Math:%f",[pmath]);
  18. NSLog(@"Math:%f",[penglish]);
  19. [prelease];
  20. [pooldrain];
  21. return0;
  22. }

程序输出为:

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对象呢?这些问题见后文描述。

你可能感兴趣的:(Objective-C)