http://my.oschina.net/u/728866/blog/90798
property,可以提供的功能有:提供成员变量的访问方法的声明、控制成员变量的访问权限、控制多线程时成员变量的访问环境 )。
property不但可以在interface,在协议protocol .和类别category中也可以使用.
synthesize的理解是:实现property所声明的方法的定义。
其实说直白就像是:property声明了一些成员变量的访问方法 ,synthesize则定义了由property声明的方法。他们之前的对应关系是
property 声明方法 ----------》 头文件(.h)中申明的方法
synthesize定义方法---------》Cpp文件(.m)中定义的方法
不过这里还有有一点细微的差别,后面我会讲到。
先讲property
大家都知道:@property(attribute1 , attribute2, ...])是@property的他的官方表达方式,所以看到attribute1, attribute2,你就应该懂的, 他的用法不是很简单。下面就对他的属性列表进行分类介绍:
下面对属性列表进行一下简单的介绍,后续会用代码来解释。
1.可读性:readonly 、readwrite
@property(readwrite,....) valueType value;
这个属性是变量的默认属性,就是如果你(readwrite and readonly都没有使用,那么你的变量就是readwrite属性),通过加入readwrite属性你的变量就会有get方法,和set方法。
property(readonly,...) valueType value;
这个属性变量就是表明变量只有可读方法,也就是说,你只能使用它的get方法。
2,assign,setter方法直接赋值,不进行任何retain操作,为了解决原类型与环循引用问题对基础数据类型 。
3,retain,setter方法对参数进行release旧值再retain新值,所有实现都是这个顺序
4,copy,setter方法进行Copy操作,与retain处理流程一样,先旧值release,再Copy出新的对象,retainCount为1。这是为了减少对上下文的依赖而引入的机制。
5 相对原文进行了修改,更便于理解.
a ) atomic的意思就是setter/getter这个函数是一个原语操作。当设置了多线程操作时,如果有两个以上线程同时调用setter的话,不会出现某一个线程执行setter全部语句之前,另一个线程开始执行setter情况,相当于函数头尾加了锁,以保证多个线程取到的东西的一致性.
b ) nonatomic不保证setter/getter的原语行,所以多线程调用时可能取到东西并不一致,比如setter函数里面改变两个成员变量,如果你用nonatomic的话,getter可能会取到只更改了其中一个变量时候的状态,这样取到的东西会有问题。
如果不需要多线程支持的话,当然nonatomic就够用了,另外由于不涉及锁操作,所以它执行相对快点.
注意,如果不加此属性,则默认是两个访问方法都为原子型事务访问。锁被加到所属对象实例级.
所以 不加nonatomic对与多线程是安全的 。
其实他们都可以用代码表示:
1.nonatomic 和 atomic
@property(nonatomic ) NSObject* test1;
@synthesize test1;
上面两句代码,表示我们对test1的访问,是非多线程安全的。
@property(atomic) NSObject* test1;
@synthesize test1;
上面两句代码,表示我们对test1的访问,是多线程安全的。其实也就是在讲该成员变量放到互斥代码中,例如,下面进行加锁。
[_internal lock]; // lock using an object-level lock
id result = [[value retain] autorelease];
[_internal unlock];
return result;
就如上面所说 ,这两个属性,是出于对多线程条件下 ,对test1的访问安全。如果你的程序的成员变量不存在安全问题,用nonatomic 就好,因为这样不要在访问是进行互斥,效率更高。
2. readonly 、readwrite (注,后续过程我们都会加入nonatomic 属性,因为它是十分普遍的)
2.1 readonly
@property(nonatomic ,readonly) NSObject* test1;
@synthesize test1;
上面的两句代码,objc编辑器将会为我们翻译为:
@property(nonatomic ,readonly) NSObject* test1; 等同
-(NSObject*)test1;
@synthesize test1;等同
-(NSObject*)test1
{
return test1;
}
2.2 readwrite
@property(nonatomic ,readwrite ) NSObject* test1;
@synthesize test1;
上面的两句代码,objc编辑器将会为我们翻译为:
@property(nonatomic ,readwrite ) NSObject* test1; 等同
-(NSObject*)test1;
-(void)settest1(NSObject* other);
@synthesize test1;等同
-(NSObject*)test1
{
return test1;
}
-(void)settest1(NSObject* other);
{
test1 = other;
}
这里要说明一下, readonly 、readwrite 这两个属性他们的真正价值,不是提供成员变量访问接口,而是控制
成员变量的访问权限。所以要抓住他们真正价值。
3. assign
@property(nonatomic ,assign) NSObject* test1;
@synthesize test1;
上面两句:objc编辑器将会翻译如下:
@property(nonatomic ,assign) NSObject* test1;等同
-(void)settest1(NSObject* other);
@synthesize test1;
-(void)settest1(NSObject* other);等同
{
test1 = other;
}
4. retain
@property(nonatomic ,retain) NSObject* test1;
@synthesize test1;
objc编辑器翻译如:
@property(nonatomic ,retain) NSObject* test1;等同
-(NSObject*)test1;
-(void)settest1(NSObject* other);
@synthesize test1;
-(NSObject*)test1
{
return test1;
}
-(void)settest1(NSObject* other)
{
if (test1!= other)
{
[test1release];
test1= [otherretain];
}
}
5. copy
@property(nonatomic ,copy) NSObject* test1;
@synthesize test1;
objc编辑器将翻译如:
@property(nonatomic ,copy) NSObject* test1;
-(NSObject*)test1;
-(void)settest1(NSObject* other);
@synthesize test1;
-(NSObject*)test1
{
return test1;
}
-(void)settest1(NSObject* other);
{
if (test1!=other) {
[test1release];
test1= [othercopy];
}
}
对于Copy属性有一点要主要,被定义有copy属性的对象必须要符合NSCopying协议,并且你还必须实现了
-(id)copyWithZone:(NSZone*)zone该方法。
代码才是王道:都是一些简单代码用例
//为了更具有普遍性,我选择用自定义对象testObj
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//testObj .h
@interface testObj : NSObject<NSCopying>{
}
@end
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//testObj .m
-(id)copyWithZone:(NSZone *)zone
{
testObj* pObj = [[testObj allocWithZone:zone] init];
return pObj;
}
@end
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//testApp是包含多个testObj 对象指针
//testApp .h
@interface testApp :
{
testObj* test1;
testObj* _test2;
}
@property(nonatomic , retain) NSObject* test1;
@property(nonatomic , copy) NSObject* test2;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//testApp.m
@synthesize test1;
@synthesize test2 = _test2;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@synthesize test2 = _test2; //对这里要特别主要一下,这里可以看作是一种别名机制,这点和前面类比的C++头文件和Cpp文件不同。
例如对于setter函数,objc编辑器将会按如下方式翻译
如果是@synthesize _test2;
setter函数将是这种形式:
-(void)set_test2(NSObject*); //注意中间的下划线
写成@synthesize test = _test2;
setter函数将是这种形式:
-(void)settest2(NSObject*);// _test2 被 test2替换了
可以看出这种别名机制,感觉是规范书写(其实更像是规范Objc的书写,大家可以看看官方文档中,成员变量都是前面带下滑线的(如_test2),所以才搞了这样一个别名规范代码中的书写)
//下面是一个功能函数,
-(void )test
{
test1 = [[testObj alloc]init];// test1 retainCount =1;
//下面有三种对test2操作方法:
_test2 = test1; //这里是将test1的指针赋值给_test2指针,注意,并没有调用test2的setter方法 ,所以test retainCount = 1、 test2 retainCount = 0;
self.test2 = test1; //这里调用test2的Copy方法,因此这是test retainCount = 1、 test2 retainCount = 1;
test2 = test1;
//这段代码系统将会提示出错说test2没有定义。因为这里编译器认为是一条赋值表达式,将test2看作是一个成员变量,而在我们的testApp 中是没有这个成员变量的,这里要区别我们所说的别名,别名机制可以看作是在调用setter或者getter函数才会起作用,而这里只是一个简单的赋值, 也就出现未定义的错误。如果没有理解,你就记住要调用setter或者getter函数,就用"self.成员变量"这种形式就行了.
//我们把 test2 = test1这行代码注释掉,保证程序继续执行
[test1 release]; // 释放test1 ,test1 retainCount = 0;
[test2 release]; // 释放test2 ,test2 retainCount = 0;
}
objective-C: nonatomic retain copy assgin 等属性详解的更多相关文章
-
Linux文件权限与属性详解 之 ACL
Linux文件权限与属性详解 之 一般权限 Linux文件权限与属性详解 之 ACL Linux文件权限与属性详解 之 SUID.SGID & SBIT Linux文件权限与属性详解 之 ch ...
-
android:exported 属性详解
属性详解 标签: android 2015-06-11 17:47 27940人阅读 评论(7) 收藏 举报 分类: Android(95) 项目点滴(25) 昨天在用360扫描应用漏洞时,扫描结果, ...
-
OutputCache属性详解(一)一Duration、VaryByParam
目录 OutputCache概念学习 OutputCache属性详解(一) OutputCache属性详解(二) OutputCache属性详解(三) OutputCache属性详解(四)— SqlD ...
-
OutputCache属性详解(二)一 Location
目录 OutputCache概念学习 OutputCache属性详解(一) OutputCache属性详解(二) OutputCache属性详解(三) OutputCache属性详解(四)— SqlD ...
-
OutputCache属性详解(三)— VaryByHeader,VaryByCustom
目录 OutputCache概念学习 OutputCache属性详解(一) OutputCache属性详解(二) OutputCache属性详解(三) OutputCache属性详解(四)— SqlD ...
-
OutputCache属性详解(四)— SqlDependency
目录 OutputCache概念学习 OutputCache属性详解(一) OutputCache属性详解(二) OutputCache属性详解(三) OutputCache属性详解(四)— SqlD ...
-
WPF依赖属性详解
WPF依赖属性详解 WPF 依赖属性 英文译为 Dependency Properties,是WPF引入的一种新类型的属性,在WPF中有着极为广泛的应用,在WPF中对于WPF Dependency P ...
-
HTML video 视频标签全属性详解
HTML 5 video 视频标签全属性详解 现在如果要在页面中使用video标签,需要考虑三种情况,支持Ogg Theora或者VP8(如果这玩意儿没出事的话)的(Opera.Mozilla.C ...
-
Android组件---四大布局的属性详解
[声明] 欢迎转载,但请保留文章原始出处→_→ 文章来源:http://www.cnblogs.com/smyhvae/p/4372222.html Android常见布局有下面几种: LinearL ...
随机推荐
-
邮件中继成畅邮标配 U-Mail为何领先
中国力推“一带一路”战略,为首成立“亚投行”,越来越多的中国企业酝酿走出去.在企业间的商务往来中,电子邮件将扮演着重要角色,但是因为要跨洋 过海,各国互联网环境和法律法规有所区别,面临着种种变数,对方 ...
-
Android -- 桌面悬浮,仿360
实现原理 这种桌面悬浮窗的效果很类似与Wid ...
-
struts2-json-plugin插件实现异步通信
用例需要依赖的jar: struts2-core.jar struts2-convention-plugin.jar,非必须, struts2-json-plugin.jar org.codehaus ...
-
JQuery-Table斑马线
HTML <html> <head> <link href="StyleSheet.css" rel="stylesheet" t ...
-
javascript进阶-原型prototype
一.javascript原型认识 很多编程语言都有类的概念,我们可以拿原型和类进行比较,看看它们之间的区别以及相同点在哪里. 1.类:类是一个具体事物的抽象所以类是一个抽象的东西,在面向对象中类可以用 ...
-
Python开发笔记之正则表达式的使用
查找正则表达式 import re re_txt = re.compile(r'(\d)*.txt') m = re_txt.search(src) if not m == None: m.group ...
-
好看的Select下拉框是如何制造的
现在在大多数网站中都能看到很华丽的Select下拉框,他们是如何实现的呢?使用默认select肯定是不好实现,我们可以使用div+js去模拟出来select的功能,并且又能很简单的去美化它. CSS代 ...
-
SAR数据下载网站
1] http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.144.2153&rep=rep1&type=pdf[2] ht ...
-
对java泛型的理解
正确的应用java泛型的特性可以更好的实现编程的开闭原则(对扩展开放,对修改关闭),这得益于java泛型提供的在程序运行时获取对象声明类型的特性. 静态语言的特性是在程序编译前进行声明,这样程序在编译 ...
-
洛谷 [P1113] 杂务
图论的做法是topsort 一看见有序我们就想到了DAG图,于是用topsort做,对于每一个加入队列的顶点,都用它的时间去更新它所指向的点的时间,本质上仍是DP的思想,dp[i]=max{dp[j] ...