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对象 ...
随机推荐
- jquery mousewheel
<script type="text/javascript" src="http://code.jquery.com/jquery-1.7.1.min.js&quo ...
- iOS之02-第一个OC的类
OC是一门面向对象的语言,因此它也有类.对象.静态\动态方法.成员变量的概念.这讲就来创建第一个OC的类. 第一个类的源码: /* 人 类名:Person 属性(成员变量\实例变量):体重.年龄 行为 ...
- 【BZOJ2243】[SDOI2011]染色 树链剖分+线段树
[BZOJ2243][SDOI2011]染色 Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的 ...
- (转)HBase工程师线上工作经验总结----HBase常见问题及分析
阅读本文可以带着下面问题:1.HBase遇到问题,可以从几方面解决问题?2.HBase个别请求为什么很慢?你认为是什么原因?3.客户端读写请求为什么大量出错?该从哪方面来分析?4.大量服务端excep ...
- Java NIO之选择器Selector
在单独的线程中,检查多个通道是否可以进行IO操作. Selector创建:静态工厂方法创建 Selector selector = Selector.open(); 注册通道 channel.conf ...
- ACM: Mr. Kitayuta's Colorful Graph-并查集-解题报
Mr. Kitayuta's Colorful GraphTime Limit:1000MS Memory Limit:262144KB 64bit IO Format:%I64d & %I6 ...
- HDU - The number of divisors(约数) about Humble Numbers
Description A number whose only prime factors are 2,3,5 or 7 is called a humble number. The sequence ...
- 【BZOJ2438】 [中山市选2011]杀人游戏 tarjan强连通分量+缩点
Description 一位冷血的杀手潜入 Na-wiat,并假装成平民.警察希望能在 N 个人里面,查出谁是杀手. 警察能够对每一个人进行查证,假如查证的对象是平民,他会告诉警察,他认识的人, 谁是 ...
- HDU-1231 简单dp,连续子序列最大和,水
1.HDU-1231 2.链接:http://acm.hdu.edu.cn/showproblem.php?pid=1231 3.总结:水 题意:连续子序列最大和 #include<iostre ...
- springmvc项目中java.lang.ClassNotFoundException: org.springframework.web.context.ContextLoaderListener
java.lang.ClassNotFoundException: org.springframework.web.context.ContextLoaderListener 严重: Error co ...
转载▼