Objective-C 中类属性(修饰)
(atomic是Objc使用的一种线程保护技术,基本上来讲,是防止在写未完成的时候被另外一个线程读取,造成数据错误。而这种机制是耗费系统资源的,所以在iPhone这种小型设备上,如果没有使用多线程间的通讯编程,那么nonatomic是一个非常好的选择。)
assign: 简单赋值,不更改引用计数;
适用于基本数据类型(例如NSInteger)和C数据类型(int,float,double,char,等)以及指针的弱引用
注:指针的弱引用,比如:delegate,在ARC模式中用weak比较好,在非ARC模式中用assign
一、非ARC模式
copy: 建立一个索引计数为1的对象,然后释放旧的对象
retain: 释放旧的对象,将旧的对象的值赋予输入对象,在提高输入对象的索引计数为1
例子:
@interface MyClass:NSObject
@property (nonatomic, copy) NSString *myString;
这里定义了一个NSString类型的属性,不需要原子操作,所以用nonatomic.
为什么需要copy,而不是retain呢! 因为如果对myString赋值原字符串是一个可变的字符串(NSMutableString)对象的话,用retain的话,当原字符串改变的时候你的myString属性也会跟着变掉。我想你不希望看到这个现象。
@property (nonatomic, retain) UIView *myView;
这里定义了一个UIView类型的属性,不需要原子操作,所以用nonatomic.
当对myView 赋值的时候原来的UIView对象retainCount会加1
@implementation MyClass
@synthesize myString;
@synthesize myView;
创建一个MyClass的对象
MyClass *object=[[MyClass alloc] init];
NSMutableString *mutString=[NSMutableString stringWithString:"hello"];
object.myString=mutString;
[mutString appendString:@"world!"];
NSLog(@"%@",mutString); 输出为“hello world!”;
NSLog(@"%@",object.myString); 输出为"hello",因为myString在mutString改变之前已经copy了一份副本
UIView *view=[[UIView alloc] init];
view的retainCount为1;
object.myView=view;
此时view的retainCount为2,因为myView对View进行了一次retain。
[view release];
此处虽然view被release释放掉了,但是myView对view进行了一次retain,那么myView保留的UIView的对象指针仍然有效。
[object release];
二、ARC模式
iOS中的ARC是随着xcode4.2一起引入的,4.2版本以前的xcode是没有这种特性的,ARC只能在iOS4 和iOS5上使用,而weak关键字只能在iOS5上使用,并且只能是工程在ARC管理内存的时候才能用。
前段时间看到别人的代码中出现了unsafe_unretained的关键字,虽然自己了解它是出自arc中的关键字,但是为了了解的更加透彻,所以上网收集了一些相关知识来记录一下,以备以后查阅;
先 来了解一下各个关键字之间的关系,和其是否拥有所有权(及保留)属性值关键字所有权strong __strong有weak__weak无unsafe_unretained__unsafe_unretained无copy__strong有 assign__unsafe_unretained无retain__strong有
strong
该属性值对应 __strong 关键字,即该属性所声明的变量将成为对象的持有者。
weak
该属性对应 __weak 关键字,与 __weak 定义的变量一致,该属性所声明的变量将没有对象的所有权,并且当对象被破弃之后,对象将被自动赋值nil。
并且,delegate 和 Outlet 应该用 weak 属性来声明。同时,iOS 5 之前的版本是没有 __weak 关键字的,所以 weak 属性是不能使用的。这种情况我们使用 unsafe_unretained。
unsafe_unretained
等效于__unsafe_unretaind关键字声明的变量;像上面说明的,iOS 5之前的系统用该属性代替 weak 来使用。
(这里需要说明一下:应尽量不要使用unsafe_unretained来声明属性,因为如果它所指向的对象被释放了,那么它将变成一个野指针,而不会是nil,如果程序试图访问该野指针就会造成crash)
copy
与 strong 的区别是声明变量是拷贝对象的持有者。
assign
一般Scalar Varible用该属性声明,比如,int, BOOL。
retain
该属性与 strong 一致;只是可读性更强一些。
读写相关的属性 (readwrite, readonly)
读写相关的属性有 readwrite 和 readonly 两种,如果使用ARC之后,我么需要注意一下 readonly 属性的使用。
比如下面的变量声明。
@property (nonatomic, readonly) NSString *name;
一般声明为 readonly 的变量按理说应该不需要持有所有权了,但是在ARC有效的情况下,将出现下面的错误信息 :
“ARCforbidssynthesizingapropertyofanObjective-C object with unspecified ownership or storage attribute 如果定义了ARC有效,那么必须要有所有者属性的定义;所以我们的代码改成这样,就OK了
@property (nonatomic, strong, readonly) NSString *name;
不过有一点,Scalar Varible的变量缺省都有 assign 的属性定义,所以不需要给他们单独的明示声明了。
有一个关键字需要特别注意一下,就是__autoreleasing
在没有开启ARC的情况下,我们可以在一个函数中使用autorelease让某个对象延迟释放,但是在开启ARC的情况下是不会通过编译,如下:
-(ClassA *)TestMethod{ ClassA *classA = [[ClassA alloc] init]; return [classA autorelease];}
在开启ARC的情况下,我们就需要使用如下方式进行替代:
-(ClassA *)TestMethod{ __autoreleasing ClassA *classA = [ClassA alloc] init]; return classA;}
或:
-(NSString *)TestMethod:(_autoreleasing ClassA *)classA{ classA = [[ClassA alloc] init]; return classA;}ARC机制让我们节省了很多代码的编写,并且也让程序在效率方面有了很大的提升,所以充分利用这个新特性对我们是非常有帮助的,但是不建议新手使用,因为它会让我们知其然而不知其所以然。
Objective-C 中类属性(修饰)的更多相关文章
- iOS 属性修饰符记录 --不定时更新
重新审视了一下OC在属性修饰符,特意记录一下来.以后不定时更新 > retain:只有在非ARC下才会有效,所有如果在ARC下使用了retain修饰也白搭 如以下的data属性用retain修饰 ...
- iOS之属性修饰符 retain、strong和copy区别测试
时不时会有点迷惑属性修饰符retain.strong.copy三者之间的区别,还是把测试过程记录下来好一点! 1.属性修饰符结论 2.给retain.strong.copy修饰的字符串属性赋值指针变化 ...
- Objective - C中属性和点语法的使用
一.属性 属性是Objective—C 2.0定义的语法,为实例变量提供了setter.getter方法的默认实现能在一定程度上简化程序代码,并且增强实例变量的访问安全性 ...
- IOS 类的属性修饰符atomic
在声明一个类的属性时,默认这个属性会被修饰atomic,意思是原子性访问的. nonatomic和atomic修饰的属性,在自己没有重写setter和getter的时候才会发生作用,其主要的作用可以理 ...
- UE4C++定义属性修饰符总结
1.BlueprintAssignable 暴露该属性来在蓝图中进行赋值,用于绑定多播委托 2.BlueprintCallable 用于从蓝图中调用C++原生函数 3.BlueprintReadO ...
- python中类属性和数据属性的解释
python中的类叫class object,类的实例叫instance object. 类 Class Objects 类拥有两种操作,1.类属性 attribute references 2.实例 ...
- ios学习路线—Objective-C(属性修饰符)
readonly: 此标记说明属性是只读的,默认的标记是读写,如果你指定了只读,在@implementation中只需要一个读取器.或者如果你使用@synthesize关键字,也是有读取器方法被解析. ...
- C#中类的修饰符
Q&A 项目=程序集=assembly 1,Q:类的修饰符有哪些? A: 有 new.public.protect.internal.private.abstract.sealed.st ...
- ES6深入浅出-5 新版对象-2.属性修饰符
对象语法增强 已经有了个对象的新增语法 还需要一个api来做呢?. 因为有的时候,你需要在旧的对象上添加get.set. 读的时候就走get 写的时候就走set 假设很早之前在项目里写了一个old对象 ...
随机推荐
- js-DOM2,表单脚本
DOM2: 1.DOM2中:创建一个完整的HTML文档 document.implementation.createHTMLDocument("new Doc"); alert(h ...
- 归并排序(Merge Sort)
归并排序是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用.将已有序的子序列合并,得到完全有序的序列:即先使每个子序列有序,再使子序 ...
- HDU1402 A * B Problem Plus(FFT)
http://acm.hdu.edu.cn/showproblem.php?pid=1402 初学FFT. http://www.cnblogs.com/WABoss/p/FFT_Note.html ...
- 2014-2015 ACM-ICPC, NEERC, Moscow Subregional Contest F. Friends
F. Friends time limit per test 2 seconds memory limit per test 256 megabytes input standard input ou ...
- iOS学习05C语言函数
本次主要是学习和理解函数,函数树状图如下: 1.函数的声明和定义 函数定义的四要素分别为: 返回值类型 :函数的结果值类型,函数不能返回数组. 指定返回类型是void类型说明函数没有返回值. 函数名 ...
- Mariadb 数据库写入中文乱码问题
从其他表里面导入数据,出现中文乱码错误.之前操作时并没有碰到类似问题,有些不得其解. 在网上搜了下,最后参考这篇文章,在执行insert前,先执行 set names gbk; 然后成功插入. 链接: ...
- awk 学习
1. awk用例 今天用awk来统计一个字符出现的次数,总是比实际多一个.查了半天才发现问题所在. 文本tt.txt如下: <lst name="responseHeader" ...
- POJ 2456 (二分)
题目链接: http://poj.org/problem?id=2456 题目大意:n个房子,m头牛,房子有一个横坐标,问将m头牛塞进房子,每两头牛之间的最大间隔是多少. 解题思路: 不难看出应该二分 ...
- Zepto Code Rush 2014 A. Feed with Candy
此题用贪心求解, 首先将caramel drop类别的糖果按照高度从小到大排序,如果高度相同,按照重量从小到大排序 将fruit drop类别的糖果按照高度从小到大排序,如果高度相同,按照重量从小到大 ...
- ubuntu13.04下安装jdk7
参考http://www.neversaydie.cc/ubuntu-install-jdk-in-detailed/ 而来 1.手工从Oralce官网下载jdk-7u25-linux-x64.gz ...
转载▼