您的位置:首页 > 移动开发 > IOS开发

iOS学习笔记3-iOS中@property和@synthesize的用法

2016-02-01 11:40 513 查看
本笔记参考了博客:Objective-C中的@property和@synthesize用法

首先,看一段代码:

1.Person.h文件中:

//代码风格是Xcode4之前的,因为在这之后,synthesize不需要我们显式写出来了。
@interface Person : NSObject
{
int _age;
}

// @property:可以自动生成某个成员变量的setter和getter声明
@property int age;

@end


2.Person.m文件中:

#import "Person.h"
@implementation Person

// @synthesize自动生成age的setter和getter实现,并且会访问_age这个成员变量
@synthesize age;//在.m文件下面可以使用这个属性了
@end


知识点

这里有两个概念

(1)实例变量: int _age;//这里的_age就是个实例变量,类似和C++只能够是一样的成员变量,可以定义在@interface里面的或者定义在.m文件中,如果定义在.h头文件里就是公有的,如果定义在.m文件就是私有类型的

(2)属性: @property int age;//这里的age就是个属性,与实例变量既有相通但又有不同;

格式

声明property的语法为:@property (参数1,参数2等) 变量类型 变量名;

例子:

@property(nonatomic,retain) UIWindow *window;

可以看出,功能是让编译好器自动编写一个与数据成员同名的方法声明来省去读写方法的声明。这一点可以从C++类似的角度去想,我们在C++中一般成员变量都是定义成私有的,所以一般都会有成员函数去获取和设置成员变量以保持封装性,在objective-c中@property就是这个道理

注意:

(1)如果写了@property和@synthesize的指令的话,则不必要再在写声明实例变量了,编译器会自动设置。

(2)如果写了@property,但是缺省@synthesize的指令的话,编译器会自动生成加上前缀“_”的实例变量;如下例子(编译器自动添加的)

@synthesize carName = _carName;
@synthesize carType = _carType;


可以看出,这里编译器默认添加了前缀“_”;

同样道理,如果我们需要制定实例变量的名字,也可以在这里取有意义的名字,如下:

// Car.m
#import "Car.h"
@implementation Car
@synthesize carName = i_am_car_name;
@synthesize carType = i_am_car_type;
- (NSString *)carInfo
{
return [NSString stringWithFormat:@"The car name is %@ and the type is %@",i_am_car_name,i_am_car_type];
}
@end


总结:如果需要指定特定名字,则在

@implementation Car
@synthesize carName = i_am_car_name;//这一行修改


如果不需要指定,则使用

@implementation Car
@synthesize carName;


(3)如果写了@property,又自定义了setter或者getter函数,则系统会调用自定义的函数,编译器忽略自己的函数。

(4)如果写了@property,那么就可以用.去访问,这个思想类比于C++。

代码如下:

Book *b = [[Book alloc] init];

// 一般的setter用法
[b setPrice:300];

// 一般的getter用法
NSLog(@"the price of the book is %d", [b price]);

// Objective-C 2.0之後可使用點語法,它會自動呼叫setter並將值傳給它
b.price = 200;

// 這裡則是呼叫getter把值傳回來
NSLog(@"the price of the book is %d", b.price);

[b release];


下面介绍参数:

1.其中参数主要分为三类:

读写属性: (readwrite/readonly)

setter语意:(assign/retain/copy)

原子性: (atomic/nonatomic)

各参数意义如下:
readwrite: 产生setter\getter方法

readonly: 只产生简单的getter,没有setter。

assign: 默认类型,setter方法直接赋值,而不进行retain操作

retain: setter方法对参数进行release旧值,再retain新值。

copy: setter方法进行Copy操作,与retain一样

nonatomic: 禁止多线程,变量保护,提高性能

默认的参数:
readwrite、assign、atomic

2.

下面详细介绍重点的参数的意义:

(1)readwrite:声明此属性为读写属性,即可以访问设置方法(setter),也可以访问获取方法(getter),与readonly互斥。

有时候为了语意更明确可能需要自定义访问器的名字

@property (nonatomic, setter = mySetter:,getter = myGetter ) NSString *name;//重点:冒号不能省略,因为要传参数


代码规范:对于bool类型一般将getter名字命名为isXX,养成习惯;

如:

@property (getter = isRich) Bool rich;


(2)readonly:声明此属性为只读属性,只能访问此属性对应的获取方法(getter),与readwrite互斥。

(3)assign: 默认类型,setter方法直接赋值,而不进行retain操作。

assign适用于基本数据类型,如int、float、double和NSInteger,CGFloat等表示单纯的复制。还包括不存在所有权关系的对象,比如常见的delegate。

例如

如果只是@property NSString*str; 则通过@synthesize自动生成的setter代码为:(默认是assign)

-(void)setStr:(NSString*)value{
str=value;
}


(4)retain:

如果是@property(retain)NSString*str; 则自动的setter内容为:

-(void)setStr:(NSString*)v{
if(v!=str){
[str release];
str=[v retain];
}
}


(5)atomic(默认,但一般不要写

atomic意为操作是原子的,意味着只有一个线程访问实例变量。atomic是线程安全的,至少在当前的存取器上是安全的。它是一个默认的特性,但是很少使用,因为比较影响效率,这跟ARM平台和内部锁机制有关。

(6)nonatomic(更加常用

nonatomic:nonatomic跟atomic刚好相反。表示非原子的,可以被多个线程访问。它的效率比atomic快。但不能保证在多线程环境下的安全性,在单线程和明确只有一个线程访问的情况下广泛使用。

3.

默认参数类型

readwrite、assign

注意:事实上,Xcode已经能够默认合成(Default Synthesis)。默认合成就不再需要显式使用@synthesize指令了,这很方便但是要注意的是,默认合成遵守的约定,这里的也就是命名规则是propertyName = _propertyName。

还有更加好的博文可以参考:

1.Objective-c的@property 详解

本文代码部分参考了以下博文:

Property and Synthesize

欢迎大家转载,记得附上链接等,希望和大家一起努力!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: