Objective-C @property
Objective-C @property
我相信对于ios开发者来说,Objective-C的@property都是不太陌生的一个概念。不过最近我参加了一次面试,在问到相关问题的时候还是感觉如鲠在喉,可见一个简单的概念想要清晰的去解释还是需要深刻的理解。故而写这篇博客来巩固一下对于OC的@property的理解。
@property是什么
@property是编译器的指令
什么是编译器的指令,编译器指令就是用来告诉编译器要做什么
@property 告诉编译器声明属性的访问器(getter/setter)方法
和@property配对使用的还有@synthesize指令
@synthesize指令:告诉编译器,生成或合成属性的访问器(getter/setter)方法
举例,原本我们需要写如下代码
@interface PropertyTest : NSObject
{
NSString *name;
}
- (NSString *)name;
- (void)setName:(NSString *)newName;
@end
使用@property和指令后
@interface PropertyTest : NSObject
{
NSString *name;
}
@property (nonatomic, strong) name;
@end
看上去不错,简洁漂亮。
如果属性很多,@property能省下的代码量将会相当可观。
@property的attribute
细心点的就会发现,每个@property括号后面都跟了一个括号,括号里面是什么东西呢?括号里面呢是@property的attribute,可以理解为@property的设置。
括号里面设置(attribute)不同,property所生成的setter方法也就不同。
有哪些设置呢?我简单列举一下:
- atomic(默认):atomic意为操作是原子的,意味着只有一个线程访问实例变量。
- nonatomic: nonatomic跟atomic刚好相反。表示非原子的,可以被多个线程访问。
- readwrite(默认):readwrite是默认的,表示同时拥有setter和getter。
- readonly: readonly 表示只有getter没有setter。
- retain:释放旧值,retain新值
- assign(默认):用于值类型,如int、float、double和NSInteger,CGFloat等表示单纯的复制。还包括不存在所有权关系的对象,比如常见的delegate。
- strong:是在ARC伴随IOS引入的时候引入的关键字是retain的一个可选的替代。表示实例变量对传入的参数要有所有权关系即强引用。strong跟retain的意思相同并产生相同的代码,但是语意上更好更能体现对象的关系。
- weak: weak跟assign的效果相似,不同的是weak在对象被回收之后自动设置为nil。而且weak智能用在iOS 5或以后的版本,对于之前的版本,使用unsafe_unretained。
- copy:copy是为是实例变量保留一个自己的副本。
atomic/nonatomic readwrite/readonly的功能都相对来说好理解
剩下的attribute跟内存管理有点关系,下面我们讲点内存管理和@property的关系
property和内存管理
内存管理听上去很高大上有木有,内存管理博大精深,不过内存管理是一个笼统的概念,并不是一个很专业的技术概念。在Objective-C里我们主要通过引用计数来达到内存管理的目的。
好吧,又来了一个概念叫引用计数。跟标题不符合啊!标题党啊!不要急,不要急,其实引用计数和内存管理是密不可分的。举一个二一点的例子。内存管理就是吃饱饭,那怎么样能吃饱饭呢?你吃米饭能吃饱,你吃面条也能吃饱。在OC里内存管理就是通过引用计数来完成,而在java里内存管理就是通过垃圾回收机制来完成。 所以接下来我们来讲讲引用计数。
>引用计数 > >这是一种古老但有效的内存管理方式。每个对象(特指:类的实例)内部都有一个retainCount的引用计数,对象刚被创建时,retainCount为1,可以手动调用retain方法使retainCount+1,同样也可以手动调用release方法使retainCount-1,调用release方法时,如果retainCount值减到0,系统将自动调用对象的dealloc方法(类似于c#中的dispose方法),开发人员可以在dealloc中释放或清理资源。
上面一段话呢是从参考资料里复制出来的,简单的来说呢,当你创建一个对象的时候,对象里面就有了一个计数retainCount,初始值为1。当你对对象做一些操作的时候可以对这个retainCount的值做一些改变。那哪些操作可以更改这个计数呢? 简单列举一下:
- retain 计数加1。
- release计数减1
- autorelease 计数减1,但是不是立即执行,而是以推迟的方式。
通过这些操作呢,我们对retainCount计数做出了修改,如果计数变为0的时候就会自动调用dealloc方法来释放对象和内存。
屁话讲了一堆,那property和内存管理有毛关系,或者说property和引用计数有毛关系。 好吧,开始进入正题了.
还记得上一节说的那个property的设置(attribute)吗
某些attribute会生成不同的set方法。那些不同的set方法里就有跟内存管理相关的内容。 让我们来看看哪些设置是根内存管理有关系的,让我来一一列举出来。
设置了assgin之后的setter方法
- (void)setName:(NSString *)newName
{
name = newName;
}
设置了retain之后的setter方法
- (void)setName:(NSString *)newName
{
if (newName != name) {
[name release]; // release旧值
name = [newName retain] //retain新值
}
}
设置了copy之后的setter方法
- (void)setName:(NSString *)newName
{
if (newName != name) {
[name release]; // release旧值
name = [newName copy] //copy新值
}
}
跟内存相关的呢主要是这三个attribute
还有两个attribute也要提及一下,就是 weak 和 strong
//weak 和 strong 分别对应 ARC 环境下的 assign 和 retain
weak / assign
strong / retain
retain 和 strong 功能基本一致
weak 和 assign 有稍许差别,weak能在对象自动销毁的时候自动赋值nil
property如果拥有以上设置,成员变量的get方法里就会有相应的retain和release操作。这就是为什么说property跟内存管理有关系了。
PS
以上就是我对@property的简单理解,随着IOS开发的经验增加,对OC有更深入的理解后,我会继续补充。文章中可能有稍许纰漏,如果有疑问,烦请提出来一起讨论!
参考资料:
http://www.cnblogs.com/andyque/archive/2011/08/03/2125728.html http://www.cnblogs.com/yjmyzz/archive/2011/02/23/1958961.html
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。