Objective-C 中类属性(修饰)

(2013-07-13 14:38:35)

标签:

it

分类: IOS笔记
nonatomic: 非原子性访问,对属性赋值的时候不加锁,多线程并发访问会提高性能。若不加此属性,则默认是两个访问方法都为原子型事务访问。
(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 中类属性(修饰)的更多相关文章

  1. iOS 属性修饰符记录 --不定时更新

    重新审视了一下OC在属性修饰符,特意记录一下来.以后不定时更新 > retain:只有在非ARC下才会有效,所有如果在ARC下使用了retain修饰也白搭 如以下的data属性用retain修饰 ...

  2. iOS之属性修饰符 retain、strong和copy区别测试

    时不时会有点迷惑属性修饰符retain.strong.copy三者之间的区别,还是把测试过程记录下来好一点! 1.属性修饰符结论 2.给retain.strong.copy修饰的字符串属性赋值指针变化 ...

  3. Objective - C中属性和点语法的使用

    一.属性        属性是Objective—C 2.0定义的语法,为实例变量提供了setter.getter方法的默认实现能在一定程度上简化程序代码,并且增强实例变量的访问安全性         ...

  4. IOS 类的属性修饰符atomic

    在声明一个类的属性时,默认这个属性会被修饰atomic,意思是原子性访问的. nonatomic和atomic修饰的属性,在自己没有重写setter和getter的时候才会发生作用,其主要的作用可以理 ...

  5. UE4C++定义属性修饰符总结

    1.BlueprintAssignable  暴露该属性来在蓝图中进行赋值,用于绑定多播委托 2.BlueprintCallable  用于从蓝图中调用C++原生函数 3.BlueprintReadO ...

  6. python中类属性和数据属性的解释

    python中的类叫class object,类的实例叫instance object. 类 Class Objects 类拥有两种操作,1.类属性 attribute references 2.实例 ...

  7. ios学习路线—Objective-C(属性修饰符)

    readonly: 此标记说明属性是只读的,默认的标记是读写,如果你指定了只读,在@implementation中只需要一个读取器.或者如果你使用@synthesize关键字,也是有读取器方法被解析. ...

  8. C#中类的修饰符

    Q&A  项目=程序集=assembly 1,Q:类的修饰符有哪些? A:   有 new.public.protect.internal.private.abstract.sealed.st ...

  9. ES6深入浅出-5 新版对象-2.属性修饰符

    对象语法增强 已经有了个对象的新增语法 还需要一个api来做呢?. 因为有的时候,你需要在旧的对象上添加get.set. 读的时候就走get 写的时候就走set 假设很早之前在项目里写了一个old对象 ...

随机推荐

  1. iOS开发-由浅至深学习block

    关于block 在iOS 4.0之后,block横空出世,它本身封装了一段代码并将这段代码当做变量,通过block()的方式进行回调.这不免让我们想到在C函数中,我们可以定义一个指向函数的指针并且调用 ...

  2. PHP、Java对称加密中的AES加密方法

    PHP AES加密 <?php ini_set('default_charset','utf-8'); class AES{ public $iv = null; public $key = n ...

  3. fill_parent 和 match_parent区别

    之前一直没有区别好 fill_parent 和 match_parent, 其实,在 api 8 以后,两者的作用几乎一样,都是填充控件 在这里延伸到android 的版本变化导致方法的变化问题 我对 ...

  4. 【Xcelsius】在PPT中嵌入水晶易表Xcelsius2008仪表盘

    如果您使用Xcelsius创建了动画图形,并将其保存为 Shockwave® 文件(.swf 文件扩展名).但是往往插入进去之后,会产生一些比较棘手的问题,比如ppt不会自动播放,错误等等.今天把这些 ...

  5. Codeforces Round #248 (Div. 2) B. Kuriyama Mirai's Stones

    题目简单描述就是求数组中[l,r]区间的和 #include <iostream> #include <vector> #include <string> #inc ...

  6. ACM 红黑树

    红黑树 时间限制:3000 ms  |  内存限制:65535 KB 难度:3   描述 什么是红黑树呢?顾名思义,跟枣树类似,红黑树是一种叶子是黑色果子是红色的树... 当然,这个是我说的... & ...

  7. ACM: POJ 1401 Factorial-数论专题-水题

    POJ 1401 Factorial Time Limit:1500MS     Memory Limit:65536KB     64bit IO Format:%lld & %llu   ...

  8. 巧用translate设置元素垂直水平居中

    之前在做手机项目时,用到很多自定义弹窗,然后要求都垂直水平要居中,最开始的时候想用calc来计算,可是css3 的calc兼容性不是很好,于是后来就借助了js来计算, 今天偶然看到别人的一个方法,瞬间 ...

  9. 【BZOJ3343】教主的魔法 分块+二分

    Description 教主最近学会了一种神奇的魔法,能够使人长高.于是他准备演示给XMYZ信息组每个英雄看.于是N个英雄们又一次聚集在了一起,这次他们排成了一列,被编号为1.2.…….N. 每个人的 ...

  10. BZOJ3625: [Codeforces Round #250]小朋友和二叉树

    Description 我们的小朋友很喜欢计算机科学,而且尤其喜欢二叉树.考虑一个含有n个互异正整数的序列c[1],c[2],...,c[n].如果一棵带点权的有根二叉树满足其所有顶点的权值都在集合{ ...