------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
编译器特性@property和@synthesize
1、@property
@property可以自动生成某个成员变量的setter和getter声明。
新建一个项目,添加Person类。
Person.h
// // Person.h // zijia // // Created by zou on 5/10/15. // Copyright (c) 2015 __MyCompanyName__. All rights reserved. // #import <Foundation/Foundation.h> @interface Person : NSObject { int _age; double _height; }
@property int age; - (void)setHeight:(double)height; - (double)height; @end
当编译器遇到@property 会自动展开对应的setter和getter声明,这里@property int age会自动展开成:
- (void)setAge:(int)age; - (int)age;
这里可以验证一下,看一下能不能在main.m中调用set和get方法。
main.m
#import <Foundation/Foundation.h> #import "Person.h" int main(int argc, const char * argv[]) { @autoreleasepool { Person *p = [Person new]; [p setAge : 10]; int a = [p age]; // int a = [p age]; NSLog(@"age is %d",a); } return 0; }
有了声明还应该有实现
Person.m
#import "Person.h" @implementation Person - (void)setAge:(int)age { _age = age; } - (int)age { return _age; } - (void)setHeight:(double)height { _height = height; } - (double)height { return _height; } @end
这里对象p调用了set和get方法,看编译能不能通过。
打印结果:
这里证明@property确实生成了成员变量的setter和getter声明。
所以这里成员变量_height的setter和getter声明也可写成@property double height;
@property double height; //- (void)setHeight:(double)height; //- (double)height; @end
二、@synthesize
@synthesize可以自动生成成员变量setter和getter实现部分,并且会访问“_成员变量”这个成员变量。
Person.m
#import "Person.h" @implementation Person @synthesize age=_age; @synthesize height=_height;
- (void)test
{
NSLog(@"age=%d,_age=%d",age,_age);
} @end
@synthesize age = _age; 等号右边的_age,表示将来set方法设置的值将会赋值给成员变量_age,这里为了验证可以添加一个成员变量int age;
Person.h
#import <Foundation/Foundation.h> @interface Person : NSObject { int _age; int age; double _height; } @property int age; @property double height; - (void)test; @end
如果在Person.m中写的是@synthesize age = age,那么set方法将来就会把值赋给成员变量age,这里可以写个test方法验证一下。
main.m
#import <Foundation/Foundation.h> #import "Person.h" int main(int argc, const char * argv[]) { @autoreleasepool { Person *p = [Person new]; [p setAge : 10]; [p test]; } return 0; }
这里编译运行一下:
通过打印结果我们发现age的值没有改变,还是默认值0,而_age的值变成了10,这里我们把Person.m里面的@synthesize age=_age,写成@synthesize age=age,重新打印一下结果发现:
age的值变成了10,而_age值为0,这说明setter方法究竟改变那个成员变量,取决于@synthesize 等号后面的变量是什么。
这里发现使用编译器特性@property和@synthesize可以避免写很多重复的代码,这里还可以更精简。
新添加一个Dog类。
Dog.h
#import <Foundation/Foundation.h> @interface Dog : NSObject @property int age; @end
这里都不用写成员变量,Dog.m里面也不用写实现的代码,@property int age这行代码做了三件事情:
第一,生成getter和setter的声明;
第二,生成了一个_age的成员变量;
第三;生成了getter和setter的实现;
这里可以验证一下:
main.m
#import <Foundation/Foundation.h> #import "Person.h" #import "Dog.h" int main(int argc, const char * argv[]) { @autoreleasepool { Person *p = [Person new]; p.age = 5; NSLog(@"age=%d",p.age); } return 0; }
打印一下结果:
这里验证了之前的说法。这里需要注意的是age默认是私有成员变量,子类是不能访问的,如果想让子类也能访问的话,需要写明成员变量。
#import <Foundation/Foundation.h> @interface Dog : NSObject { int _age; } @property int age; @end
@property age; 默认会访问age这个成员变量,如果没有age就会自动生成@private类型的age。
@synthesize age; 默认会访问age这个成员变量,如果没有age就会自动生成@private类型的age。
自从Xcode 4.x之后,@property功能就涵盖了@synthesize的功能,@synthesize就可以省略不写。
如果手动实现setter方法,编译器就会自动生成getter方法和带下划线的成员变量。
如果手动实现getter方法,编译器就会自动生成setter方法和带下划线的成员变量。
如果手动实现setter和getter方法,编译器就不会生成getter和setter方法,也不会生成带下划线的成员变量。
黑马程序员---Objective-C基础学习---编译器特性@property和@synthesize
原文:http://www.cnblogs.com/zss-itcast/p/4493068.html