OC:copy/strong/weak..使用总结☀️

  • 版权声明:本文为博主原创文章,未经博主允许不得转载。
  • 原文档关于自动引用说明:

Automatic Reference Counting (ARC) is a compiler feature that provides automatic memory management of Objective-C objects. Rather than having to think about retain and release operations, ARC allows you to concentrate on the interesting code, the object graphs, and the relationships between objects in your application.

  • 翻译过来就是:
    Automatic Reference Counting (ARC)是一个编译器的特性,提供了对iOS对象的自动内存管理,ARC在编译期间自动在适当的地方添加ObjC对象的retainrelease操作代码,而不需要我们关心。

ARC在编译期间,根据Objective-C对象的存活周期,在适当的位置添加retain和release代码。从概念上讲,ARC与手动引用计数内存管理遵循同样的内存管理规则,但是ARC也无法防止循环强引用。

ARC还引入了新的修饰符来修饰变量和声明属性。
    ·   声明变量的修饰符:__strong, __weak, __unsafe_unretained, __autoreleasing;
    ·   声明属性的修饰符:strong, weak, unsafe_unretained。
    ·   对象和Core Foundation-style对象直接的转换修饰符号:__bridge,__bridge_retained或CFBridgingRetain, __bridge_transfer或CFBridgingRelease。
    ·   对于线程的安全,有nonatomic,这样效率就更高了,但是不是线程的。如果要线程安全,可以使用atomic,这样在访问是就会有线程锁。```

#####记住内存管理法则:谁使对象的引用计数+1,不再引用时,谁就负责将该对象的引用计数-1。


- 下面我们来声明一个Person类来学习:

```swift
@interface Person : NSObject

// 注意:苹果有命名规范的,命名属性时,不能以copy开头。
// 如果下面的属性声明为copyString,会编译不通过。
@property (nonatomic, copy) NSString *copiedString;

// 默认会是什么呢?
@property (nonatomic) NSString *name;
// 默认是strong类型
@property (nonatomic) NSArray *array;

@end```

如果属性没有指定类型,默认是什么呢?其实是`strong`。如果证明呢?验证方法:分别将array属性的类型分别设置为`weak, assign,strong`,不设置,这四种情况的结果分别是:第一种打印为空,第二种直接直接崩溃,第三种和最后一种是可以正常使用。如下面的验证代码:

Person *lili = [[Person alloc] init];
lili.name = @"LiLi";
lili.copiedString = @"LiLi' father is LLL";
lili.array = @[@"谢谢", @"感谢"];

NSArray *otherArray = lili.array;
lili = nil;
NSLog(@"%@", otherArray);


再继续添加下面的代码。默认声明变量的类型为`__strong`类型,因此上面的`NSArray *otherArray = lili.array;`与`__strong NSArray *otherArray = lili.array;`是一样的。如果我们要使用弱引用,特别是在解决循环强引用时就特别重要了。我们可以使用`__weak`声明变量为弱引用,这样就不会增加引用计数值。

__strong NSArray *strongArray = otherArray;
otherArray = nil;
// 打印出来正常的结果。
NSLog(@"strongArray = %@", strongArray);

__weak NSArray * weakArray = strongArray;
strongArray = nil;
// 打印出来:null
NSLog(@"weakArray: %@", weakArray);```

xib/storybard连接的对象为什么可以使用weak?
@property (nonatomic, weak) IBOutlet UIButton *button;

像上面这行代码一样,在连接时自动生成为weak。因为这个button已经放到view上了,因此只要这个View不被释放,这个button的引用计数都不会为0,因此这里可以使用weak引用。

如果我们不使用xib/storyboard,而是使用纯代码创建呢?
@property (nonatomic, weak) UIButton *button;```

>使用weak时,由于button在创建时,没有任何`强引用`,因此就有可能提前释放。Xcode编译器会告诉我们,这里不能使用weak。因此我们需要记住,只要我们在创建以后需要使用它,我们必须保证至少有一个强引用,否则引用计数为0,就会被释放掉。对于上面的代码,就是由于在创建时使用了weak引用,因此button的引用计数仍然为0,也就是会被释放,编译器在编译时会检测出来的。

这样写,在创建时通过`self.button = ...`就是出现错误,因为这是弱引用。所以我们需要声明为强引用,也就是这样:

@property (nonatomic, strong) UIButton *button;```

block声明使用copy.

在使用block时,尽量使用typedef来起一个别名,这样更容易阅读。

使block作为属性时,使用copy

typedef void (^Block)(NSString *name);

@property (nonatomic, copy) Block testBlock;```

#####属性声明修饰符


- 属性声明修饰符有:`strong, weak, unsafe_unretained, readWrite`,默认`strong`, `readWrite`的。
    ·   `strong`:`strong`和`retain`相似,只要有一个strong指针指向对象,该对象就`不会被销毁`
    ·   `weak`:声明为`weak`的指针,`weak`指针指向的对象一旦被释放,`weak`的指针都将被赋值为`nil`;
    ·   `unsafe_unretained`:用`unsafe_unretained`声明的指针,指针指向的对象一旦被释放,这些指针将成为野指针。

@property (nonatomic, copy) NSString *name;
// 一旦所指向的对象被释放,就会成为野指针
@property (nonatomic, unsafe_unretained) NSString *unsafeName;

lili.name = @"Lili";
lili.unsafeName = lili.name;
lili.name = nil;
// unsafeName就变成了野指针。这里不会崩溃,因为为nil.
NSLog(@"%@", lili.unsafeName);```

总结

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

推荐阅读更多精彩内容