属性问题整理-Version0.3

内容针对ARC版本而言 如有遗漏和错误 还望指正

属性的使用场景


一般而言
delegate、UI控件用weak
block、NSString用copy
基本数据类型int\float\BOOL\枚举\结构体 id 用assign
上述对象外用strong

属性的介绍


assign与weak

assign与weak都是简单赋值,不更改索引计数。

assign看起来跟weak一样,其实不能混用的,assign的变量在释放后并不设置为nil(和weak不同),当你再去引用时候就会发生错误。

两个的差别在于,weak用于对象类型,就是指针类型,而assign用于简单的数据类型,如int BOOL 等。

基本数据类型不属于对象,它的创建和使用都是在栈中,超出对应方法体即被清除,所以不需要使用垃圾处理机制,无需记录索引值,所以使用assgin。

assign是指针赋值,不对引用计数操作,使用之后如果没有置为nil,可能就会产生野指针;而weak一旦不进行使用后,永远不会使用了,就不会产生野指针!
对应__weak关键字,与assign 相对应.weak用在arc下,assign用在mrc情况下用,weakassign多了一个在内存被销毁的情况下自动nil,防止野指针出现.
UI控件之所以可以用弱指针 是因为控制器有强指针指向self.view, self.view有强指针指向subviews数组 数组中有强指针指向控件,代理必须是weak 因为代理一般都指向控制器 会造成循环引用 造成内存泄露.

strong

对应__strong关键字,即该属性所声明的变量将成为对象的持有者.与retain相对应,使用了引用计数,retain+1,release -1;当引用 计数为0时,dealloc会被调用,内存被释放

copy

对应__strong关键字,建立一个索引计数为1的对象,然后释放旧的对象.用于非共享内存时,每个指针有自己的内存空间.与strong 的区别是声明变量是拷贝对象的持有者.
用copy的属性set 方法不能直接赋值要用 _xx = [xx copy]

atomic(默认)

线程安全型,在多线程中只能有一个线程能对它进行访问,非ARC编译环境下,需要设置访问锁来保证对该变量进行正确的get/set,防止在写未完成的时候被另外一个线程读取,造成数据错误。

nonatomic

非原子性访问
非线程安全型,多个线程可以同时对其进行访问,当两个不同的线程对其访问时,容易失控.
总结:atomic和nonatomic用来决定编译器生成的getter和setter是否为原子操作。在多线程环境下,原子操作是必要的,否则有可能引起错误的结果。加了atomic,setter函数会变成下面这样:
<code>
if (property != newValue) {
[property release];
property = [newValue retain];
}
</code>

readonly

只有get方法,没有set方法.

readwrite

默认属性,有get/set方法.

unsafe_unretauined

对应关键字__unsafe_unretained,声明一个弱应用,但是不会自动nil化,也就是说,如果所指向的内存区域被释放了,这个指针就是一个野指针了.所以很少使用用在ARC编译环境下,与assign相似.用于iOS 5之前的系统

__block

在block内部访问并修改外部变量时 外部变量需要用__block修饰
只是引用的话不需要

属性的使用场景


@interface ViewController : UIViewController
{
//成员变量
    NSArray *array1;
}
//属性变量
@property (nonatomic,strong) NSArray *array2;
@end
-(void)viewDidLoad
{
    [super viewDidLoad];
    array1 = [[NSArray alloc] initWithObjects:@"abcde", nil];
    array2 = [[NSArray alloc] initWithObjects:@"123abc", nil];
{
//        局部变量
    NSArray *array1 = [[NSArray alloc] initWithObjects:@"12345", nil];
}
    NSLog(@"\narray1 : %@\n array2 : %@",array1,array2);
}

局部变量是根据其生存周期定义的,在源文件中的array1,其生命周期是在以“{ }”为界限的代码块中,虽然它的名称与成员变量相同,但不是同一个变量。成员变量是用于一个区域内的临时变量。

成员变量,本例中的是实例成员变量,是作用于整个类对象内的。从生命周期来看,它比局部变量要长一些,但它默认是私有的,其他对象是无法访问到的。因此,一般自定义方法,作为一个接口让其他对象访问这个变量。因此,成员变量用于类内部,无需与外界接触的变量。
封装
如果成员变量是private,程序中的其它对象很难直接访问该成员变量。如果是属性,相对更容易用父类方法读写属性。

性能
成员变量地址可以根据实例的内存地址偏移寻址。而属性的读写都需要函数调用,相对更慢。

非基础类型
对于复杂的C++类型,往往设为成员变量更合适,也许这种类型不支持copy,或者完全复制很麻烦。

多线程
多线程环境下,为保证数据一致性,在需要同步执行的代码段更应该使用成员变量。如果对需要同步更新的数据用getter/setter 方法,数据更新效率低,会带来更多的获取锁请求失败。

程序正确性
成员变量可以做直观的内存管理。属性可以一层层继承,还可以复写。容易出错。

二进制文件的体积
默认用属性,会生成不必要的getter/setter 方法,程序体积会变大。
根据成员变量的私有性,为了方便访问,所以就有了属性变量。属性变量的好处就是允许让其他对象访问到该变量。当然,你可以设置只读或者可写等,设置方法也可自定义。所以,属性变量是用于与其他对象交互的变量。

后记:

没写属性的变量的默认 都是strong 缺省关键字就是__strong

在用到block时的__block和__weak
__block不管是ARC还是MRC模式下都可以使用,可以修饰对象,还可以修饰基本数据类型修饰对象可以在block中被重新赋值。
__weak只能在ARC模式下使用,也只能修饰对象,不能修饰基本数据类型被修饰过的也并不可以重新赋值,目前见到和block一起用的最多的就是防止循环引用.__weak typeof(self) share = self

关键字__autoreleasing

__autoreleasing 都是用来修饰变量的.
__autoreleasing 如用来修饰一个函数的参数,这个参数会在函数返回的时候被自动释放.
在MRC下,使用autorelease让某个对象延迟释放
-(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;}

strong 和copy


strong

copy

https://www.mgenware.com/blog/?p=2121
http://blog.csdn.net/liushuo19920327/article/details/51465318
http://www.cnblogs.com/csj007523/archive/2012/07/23/2605662.html
http://www.cnblogs.com/langtianya/p/3722129.html

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,383评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,522评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,852评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,621评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,741评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,929评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,076评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,803评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,265评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,582评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,716评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,395评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,039评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,027评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,488评论 2 361
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,612评论 2 350

推荐阅读更多精彩内容

  • __block和__weak修饰符的区别其实是挺明显的:1.__block不管是ARC还是MRC模式下都可以使用,...
    LZM轮回阅读 3,293评论 0 6
  • 多线程、特别是NSOperation 和 GCD 的内部原理。运行时机制的原理和运用场景。SDWebImage的原...
    LZM轮回阅读 2,004评论 0 12
  • iOS面试小贴士 ———————————————回答好下面的足够了------------------------...
    不言不爱阅读 1,970评论 0 7
  • ———————————————回答好下面的足够了---------------------------------...
    恒爱DE问候阅读 1,712评论 0 4
  • 史上最全的iOS面试题及答案 iOS面试小贴士———————————————回答好下面的足够了----------...
    Style_伟阅读 2,346评论 0 35