您的位置:首页 > 移动开发 > Objective-C

黑马程序员---Objective-C基础学习---编译器特性@property和@synthesize

2015-05-10 21:07 471 查看
------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------

[b]编译器特性@property和@synthesize[/b]

[b]1、@property[/b]

@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


[b]二、@synthesize[/b]

@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方法,也不会生成带下划线的成员变量。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: