基础篇 iOS 强弱引用

原文连接:http://blog.csdn.net/xumugui007/article/details/50960907app

强引用和弱引用:ui

咱们已经知道OC中的内存管理是经过“引用计数器”来实现的。一个对象的生命周期取决于它是否还被其余对象引用(是否retainCount=0)。但在有些状况下,咱们并不但愿对象的销毁时间由是否被其余对象引用来决定,而是这个对象本该是何时销毁就何时被销毁。这时,咱们得引入“强引用”和“弱引用”的概念。url

强引用:当前对象被其余对象引用时,会执行retain操做,引用计数器+1。当retainCount=0时,该对象才会被销毁。由于咱们要进行对象的内存管理,因此这是默认的引用方式。(默认是强引用)spa

弱引用:当前对象的生命周期不被是否由其余对象引用限制,它本该何时销毁就何时被销毁。即便它的引用没断,可是当它的生存周期到了时就会被销毁。.net

在定义属性时,若声明为retain类型的,则就是强引用;若声明为assign类型的,则就是弱引用。后来内存管理都由ARC来完成后,如果强引用,则就声明为strong;如果弱引用,则就声明为weak。指针

因此说,retain和strong是一致的(声明为强引用);assign和weak是基本一致的(声明为弱引用)。 之因此说它俩是基本一致是由于它俩仍是有所不一样的,weak严格的说应当叫“  归零弱引用 ”,即当对象被销毁后,会自动的把它的指针置为nil,这样能够防止野指针错误。而assign销毁对象后不会把该对象的指针置nil,对象已经被销毁,但指针还在痴痴的指向它,这就成了野指针,这是比较危险的。 code

避免“强引用循环“的僵局:对象

默认的引用方式是强引用,但上面说了有时咱们还得使用弱引用,那是什么状况呢? blog

答案,强引用循环:A对象强引用了B对象,B对象也强引用了A。由于都是强引用,也就是不管是A是B都要在对方的引用断了后才能销毁,但要断了引用,就必须对方对象销毁。就会出现这种僵局,为了不出现这种状况,就应该有一个对象“示弱”,使其为“弱引用”。  生命周期

比较常见的,视图中的父子视图之间的引用:父视图强引用子视图,子视图弱引用父视图。

总结:因为要进行内存管理的缘故,OC里的引用默认都是强引用,但为了不出现”强引用循环僵局“,因此有了弱引用(assign)。

关于copy:  参考连接

retain和strong都是  指针拷贝。 当有其余对象引用当前对象时,会拷贝一份当前对象的地址,这样它就也指向当前对象了。因此,仍是同一个对象,只是retainCount+1; 

而copy则是  内容拷贝。 是实实在在的拷贝一个新的对象,拷贝了它的内存内容,成为一个新的对象(retainCount=1)。 

深拷贝(mutableCopy)和浅拷贝(copy):

深拷贝就是内容拷贝,浅拷贝就是指针拷贝。

在OC中,若要进行对象的拷贝,则该对象所属的类必须遵照NSCopying和NSMutableCopy协议,并重写copyWithZone:和mutableCopyWithZone:方法。而系统原生类,之因此能够直接进行拷贝是由于它已帮咱们自动作了这些事

 

在Objective-C的ARC模式中, 

?

1

id obj1 = [[NSObject alloc] init];

这里虽然没有显示的声明为__strong,可是Objective-C默认声明的一个对象就为__strong,即: 

?

1

id obj1 = [[NSObject alloc] init];

和 

?

1

id __strong obj1 = [[NSObject alloc] init];

是等价的。

在强引用中,有时会出现循环引用的状况,这时就须要弱引用来帮忙(__weak)。 

强引用持有对象,弱引用不持有对象。 

强引用能够释放对象,但弱引用不能够,由于弱引用不持有对象,当弱引用指向一个强引用所持有的对象时,当强引用将对象释放掉后,弱引用会自动的被赋值为nil,即弱引用会自动的指向nil。 

下面用代码来讲明: 

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

//

//  main.m

//  ARC中的强引用和弱引用

//

//  Created by on 15/3/31.

//  Copyright (c) 2015年 apple. All rights reserved.

//

 

#import <Foundation/Foundation.h>

 

int main(int argc, const char  * argv[]) {

    @autoreleasepool {

        id __weak obj0 = nil;

        if (YES) {

            id obj1 = [[NSObject alloc] init];

            obj0 = obj1;

            NSLog(@"obj0: %@", obj0);

        }

        NSLog(@"obj0: %@", obj0);

    }

    return 0;

}

 

/*

 *  输出结果

 *  obj0: <NSObject: 0x1003066c0>

 *  obj0: (null)

 *

 *  由于obj1生成的默认的为强引用(__strong),在超出if的做用域以后,obj1所持有的对象被释放,

 *  obj0为弱引用,因此obj0不持有对象,在obj1对象释放后,obj0自动的被赋值为nil

 *  弱引用的特性是,不持有对象,即使是写成id __weak obj1 = [[NSObject alloc] init];

 *  此代码系统会给与警告,由于这里obj1被声明成弱引用,那么在赋值以后,alloc出来的对象会被当即释放。

相关文章
相关标签/搜索