作用域

OC之点语法、成员变量作用域、@property和@synthesize


一、点语法

1) 点语法基本概念:当我们使用面向对象的封装特性后,将成员变量私有化,采取使用setter方法和getter方法向外面提供成员变量访问方案。那么我们知道,OC的调用方法的方式是很独特的,采用的是  [对象名(类名)  方法名]  的方式 ,那么很多Java、C#程序员就不习惯了,在Java、C#这些主流的面向对象语言中,调用方法的方式都是采用  对象名(类名).方法名(), 如果成员变量采取public访问权限时,还可以直接   对象名.成员变量 = 值;  的形式。可能是出于让Java、C#程序员迅速习惯OC的语法,苹果公司让OC诞生了点语法。
    2)点语法代码初体验

首先,我们声明一个Person类

Person.h
[objc]  view plain  copy
 
  1. //  
  2. //  Person.h  
  3. //  04-点语法  
  4. //  
  5.   
  6.   
  7. #import <Foundation/Foundation.h>  
  8.   
  9. @interface Person : NSObject  
  10. {  
  11.     int _age;  
  12.     NSString *_name;  
  13. }  
  14.   
  15. - (void)setAge:(int)age;  
  16. - (int)age;  
  17.   
  18.   
  19. - (void)setName:(NSString *)name;  
  20. - (NSString *)name;  
  21.   
  22. @end  


Person.m
[objc]  view plain  copy
 
  1. #import "Person.h"  
  2.   
  3. @implementation Person  
  4.   
  5. - (void)setAge:(int)age  
  6. {  
  7.     _age = age;  
  8.       
  9. }  
  10.   
  11. - (int)age  
  12. {  
  13.      
  14.     return _age;  
  15.      
  16. }  
  17.   
  18. - (void)setName:(NSString *)name  
  19. {  
  20.     _name = name;  
  21. }  
  22.   
  23. - (NSString *)name  
  24. {  
  25.     return _name;  
  26. }  
  27.   
  28. @end  

测试程序:
[objc]  view plain  copy
 
  1. #import <Foundation/Foundation.h>  
  2. #import "Person.h"  
  3.   
  4. int main(int argc, const charchar * argv[])  
  5. {  
  6.     Person *p = [Person new];  
  7.       
  8.     // 点语法的本质还是方法调用  
  9.     p.age = 10// [p setAge:10];  
  10.       
  11.     int a = p.age// [p age];  
  12.       
  13.       
  14.     p.name = @"Jack";  
  15.       
  16.     NSString *s = p.name;  
  17.       
  18.     NSLog(@"%@", s);  
  19.       
  20.     return 0;  
  21. }  



注意点:
1)点语法的本质是调用类的getter方法和setter方法,如果类中没有getter方法和setter方法就不能使用点语法。
点语法本质:
[objc]  view plain  copy
 
  1. // 点语法的本质还是方法调用  
  2.     p.age = 10// [p setAge:10];  
  3.       
  4.     int a = p.age// [p age];  

2)下面的不恰当调用,会导致死循环
[objc]  view plain  copy
 
  1. // 会引发死循环  
  2.     //self.age = age; // 相当于在调用 [self setAge:age];  
  3. }  

[objc]  view plain  copy
 
  1. // 会引发死循环  
  2.     //return self.age;//相当于 [self age];  




二、成员变量作用域

  @public : 在任何地方都能直接访问对象的成员变量
 
  @private : 只能在当前类的对象方法中直接访问(@implementation中默认是@private)
 @protected : 可以在当前类及其子类的对象方法中直接访问  (@interface中默认就是@protected)
 
  @package : 只要处在同一个框架中,就能直接访问对象的成员变量
 
 
 
[objc]  view plain  copy
 
  1. @public // 在任何地方都能直接访问对象的成员变量  
  2.    int _age;  
  3.      
  4.      
  5.    @private  // 只能在当前类的对象方法中直接访问  
  6.    int _height;  
  7.      
  8.    @protected // 能在当前类和子类的对象方法中直接访问  
  9.    int _weight;  
  10.    int _money;  


注意:
1) @interface和@implementation中不能声明同名的成员变量
2)子类继承父类,子类拥有父类的@public和@protected修饰的成员变量
3)如果在类中声明一个属性,没有指定访问权限,默认是@protected


三、@property 和  @synthesize

 这两个关键字的出现,就是为了剔除代码中的setter方法和getter方法

1)@property

[objc]  view plain  copy
 
  1. // @property:可以自动生成某个成员变量的setter和getter声明  
  2. @property int age;  
  3.   
  4. //相当于下面这两句:  
  5. - (void)setAge:(int)age;  
  6. - (int)age;  
2)@synthesize

[objc]  view plain  copy
 
  1. // @synthesize自动生成age的setter和getter实现,并且会访问_age这个成员变量  
  2. @synthesize age = _age;  
  3.   
  4. @synthesize height = _height;  
  5.   
  6. @synthesize weight = _weight, name = _name;  


这样,我们就省去了写setter方法和getter方法的时间,当然写那个也是极其无聊也是毫无意义。

但是,即便是这样,还是很不爽,在xcode的老版本中,为了避免书写setter方法和getter方法,我们还必须要在@interface 和 @end之间写上 @property int _age; 在@implementation 和 @end 之间写上 @synthesize的代码,很幸运,你们生活在一个幸福的时代,自从xcode4.4之后,@property int _age; 这句代码就把@property和@synthesize的活儿都给干了。
它主要做了下面这几件事:
1)生成_age成员变量的get和set方法的声明;
2)生成_age成员变量set和get方法的实现;
3)生成一个_age的成员变量。

当然,@property方法生成的getter方法和setter方法可能满足不了您的需求,您也可以自己手动添加getter方法和setter方法,如果手动写了setter方法@property就不会生成setter方法,但还是会生成getter方法,getter同理,如果您将setter方法,getter方法都进行手动书写了,@property将不会为您生成相应的getter方法和setter方法。

你可能感兴趣的:(作用域)