首页 > 代码库 > 黑马程序员 04-@property增强(神器)
黑马程序员 04-@property增强(神器)
———Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ———
1、@property 增强的介绍
1> Xcode 4.4之后,@property 独揽了 @synthesize 的功能,也就是说@property可以同时生成sette和getter的声明和实现
2>默认情况下,setter 和 getter的实现中,会去访问下划线_开头的成员变量
例如:
1 #import <Foundation/Foundation.h> 2 @interface Dog : NSObject 3 @property int age; 4 @end 5 6 @implementation Dog 7 @end 8 9 int main()10 {11 Dog *d = [Dog new];12 d.age = 5;13 NSLog(@"狗的年龄:%i岁", d.age);14 }
分析:我们没有声明成员变量_age,也没有实现,但是却能正常运行程序。
@property 增强后可以完成以下3件事:
(1)声明成员变量
(2)实现成员变量
(3)创建一个成员变量
第3行:@property int age; 就完成了上面所说的3件事,因此无需在@interface中声明和@implementation中实现_age变量,同时创建了一个成员变量_age。
2、注意点
由于没有在@interface中声明成员变量,在@implementation中会默认生成@private类型的成员变量
即:在@implementation @end之间生成了一个_age变量,并且变量的作用域为@private(私有),只有在本类中可以直接访问,外界要访问,就得使用set get方法来间接访问。这也算是一个局限性。
3、细节问题
(1)@synthesize age = _age;
1>setter getter实现中会访问成员变量_age;
2>如果成员变量不存在,就会自动生成一个@private的成员变量_age
(2)@synthesize age; 没有具体指定访问哪个成员变量。
1>setter getter实现中为访问成员变量age
2>如果成员变量不存在,就会自动生成一个@private的成员变量age
代码如下:
1 #import <Foundation/Foundation.h> 2 @interface Dog : NSObject 3 int _age; 4 5 @property int age; 6 @end 7 8 @implementation Dog 9 @synthesize age;10 @end11 12 int main()13 {14 Dog *d = [Dog new];15 d.age = 5;16 NSLog(@"%i", d.age);17 }
第9行@synthesize age;没有具体说明要访问哪个成员变量,这时候它会优先访问跟它名称一样的成员变量,即age变量。发现没有age变量,就会在实现中自动生成一个@private的age变量。
如图:说明访问的是age变量,而不是_age变量。
(3)手动实现
1>若手动实现了setter方法,编译器就只会自动生成getter方法
1 #import <Foundation/Foundation.h> 2 @interface Dog : NSObject 3 @property int age; 4 @end 5 6 @implementation Dog 7 - (void)setAge: (int)age; 8 { 9 _age = 10;10 }11 12 @end13 14 int main()15 {16 Dog *d = [Dog new];17 d.age = 5;18 NSLog(@"%i", d.age);19 }
分析:
a> 由于我们自己书写了setter的实现,编译器只会自动生成getter的实现和创建成员变量_age
b> 运行程序:第17行 d.age 调用setter 给_age 赋值,这时由于setter方法的实现是我们手动书写的,编译器会默认尊重用户的选择,所有_age的值为10。
如图:
运行输出结果为10。如图:
2>若手动实现了getter方法,编译器就只会自动生成setter方法
1 #import <Foundation/Foundation.h> 2 @interface Dog : NSObject 3 @property int age; 4 @end 5 6 @implementation Dog 7 - (int)age 8 { 9 return 10;10 }11 12 @end13 14 int main()15 {16 Dog *d = [Dog new];17 d.age = 5;18 NSLog(@"%i", d.age);19 }
分析:
1>在@implementation中,由于我们手动书写了getter的实现,编译器就不在自动生成getter的实现
2>编译器只生成setter的实现和成员变量_age
3>运行程序:第17行 d.age = 5;对_age进行了赋值, _age 的值变为5,如图
但是到第18行, d.age 调用getter,这时去@implementation中寻找,找到我们自己书写的 getter 实现, 输出结果为:10 如图:
3>若同时实现了setter和getter方法,编译器就不会自动生成不存在的成员变量
分析:
1>由于我们手动书写了setter 和 getter 的实现,编译器默认没有实现使用成员变量,就不在自动生成_age。
2>由于缺少成员变量,于是出现报错
黑马程序员 04-@property增强(神器)