• 弱指针


    ARC是苹果为了简化程序员对内存的管理,推出的一套内存管理机制,使用ARC机制,对象的申请和释放工作会在运行时,由编译器自动在代码中添加retain和release

    1> strong:强指针引用的对象,在生命周期内不会被系统释放,OC中,对象默认都是强指针

    2> weak:弱指针引用的对象,系统会立即释放,弱指针可以指向其他已经被强指针引用的对象

    他们都是 arc 的东西

     

    ARC的判断准则:

    只要没有强指针指向对象,就会释放对象,弱指针不会这样,及时有弱指针指向对象,对象没有强指针指向,也会自动释放掉。一般,无需显式声明为强指针,但是在封装里,定义方法的时候需要写明。而弱指针,必须显式说明。默认是强指针。

     

    ARC特点

     1> 不允许调用release、retain、retainCount

     2> 允许重写dealloc,但是不允许调用[super dealloc]

    技术分享

     3> @property的参数

      * strong :成员变量是强指针(适用于OC对象类型)

      * weak :成员变量是弱指针(适用于OC对象类型)

      * assign : 适用于非OC对象类型

     4> 以前的retain改为用strong

     

    oc的指针分2种:

     1> 强指针:默认情况下,所有的指针都是强指针 __strong

     2> 弱指针:__weak

     

    在 点m 文件

    #import "Dashuai.h"
    
    @implementation Dashuai
    - (void)dealloc
    {
        NSLog(@"对象被销毁了!");
        //[super dealloc];
    }
    @end

    在视图控制器

    @interface ViewController ()
    @property (nonatomic, strong) Dashuai  *da;
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        self.da = [[Dashuai alloc] init];
        NSLog(@"调用了 viewdidlowd 方法!");
    }
    @end

    对象不销毁,da 是强指针对象。

    如果是在方法内部,声明的对象(默认都是强指针),那么存在一个声明周期(局部变量)的问题。方法执行完毕,到关括号完毕,内存也就随机自动销毁了。

    - (void)viewDidLoad {
        [super viewDidLoad];
        //self.da = [[Dashuai alloc] init];
        Dashuai *dashuai = [[Dashuai alloc] init];
        NSLog(@"调用了 viewdidlowd 方法!");
    }

    2015-03-08 17:12:33.240 strong weak[20017:738240] 调用了 viewdidlowd 方法!

    2015-03-08 17:12:33.241 strong weak[20017:738240] 对象被销毁了!

     

    如果换__weak,那么语句执行完毕,立即释放内存,加断点课证明

    技术分享

    2015-03-08 17:15:41.480 strong weak[20062:739972] 对象被销毁了!

    (lldb) 

     

    下面看堆栈图

    上例,强指针的话,那么指针变量dashuai在内存的栈区,仅仅是内存的地址,指向的内存在堆区,

    技术分享

    等指针不再指向这块内存,或者声明周期结束,内存才释放

    技术分享

     

    对于弱指针指向,是虚线

    技术分享

    执行之后,对象内存立即被释放。

     

    再看控件之间,如图:

    技术分享

    视图控制器强引用 view,view 强引用了子控件。

    [self.view addSubView];//让 view 对控件强引用

    那么这就是以前写代码的时候,连线故事板的控件和代码关联的时候,总是默认weak的原因。因为那是视图控制器在引用子控件,而 view 已经 strong 了,那么视图控制器就没必要 strong。它的内存释放过程是:

    技术分享   技术分享  技术分享

     

    如果程序没有必要弄强引用,那么就用若引用,类比是链表,一条龙,视图和姿势图,只一个实线连接(父类对象,强引用子类对象之后),其余的引用用 weak虚线,因为view 已经对子控件强引用了,视图控制器可以不用 strong。这是苹果的应用内存管理机制。当然用 strong 也不是不可以。

     

    还有之前提到的懒加载

    控件的懒加载,是手动的写类属性的 set 方法,进行是否已经加载等的判断,避免重复加载的过程。那么手写 set ,在 viewdidload重写代码,就要用 strong 引用,因为是手写代码,那么如果还是 weak ,在 viewdidload 方法里,使用控件对象,那么一旦执行完毕,立即内存被释放,因为是 weak 的。这样在视图加载之前,对象就已经消失了。

     

    注意下面的方法调用时间

    init方法-初始化程序viewDidLoad方法-加载视图viewWillAppear方法在,UIViewController对象的视图即将加入窗口时调用;

    viewDidApper方法在UIViewController对象的视图已经加入到窗口时调用;

    viewWillDisappear方法咋UIViewController对象的视图即将消失、被覆盖或是隐藏时调用;

    viewDidDisappear方法在UIViewController对象的视图已经消失、被覆盖或是隐藏时调用;

    didReceiveMemoryWarning -在内存不足时候调用

     

    @property参数使用小结:

    1> 控件用weak

    2> 属性对象用strong

    3> 非对象类型用assign

    4> 字符串NSString用copy(不是可变字符串)

     提示:在纯手码实现界面布局时,如果通过懒加载处理界面控件,需要使用strong强指针

  • 相关阅读:
    c++:资源管理(RAII)、new/delete的使用、接口设计与声明、swap函数
    C++普通链表增删、倒序打印
    Android-UI:按钮监听&文字/图片/进度条&动态变更&dialog&布局&自定义布局/控件/响应事件
    Android-活动生命周期&Bundle回收临时数据&活动启动模式&常用技巧
    C++字符串空格替换题
    C++二维数组查找题
    c++:const、初始化、copy构造/析构/赋值函数
    C++赋值运算符函数
    Android-活动创建&Toast&Menu&Intent
    用yarn代替cnpm,cnpm漏包有点严重
  • 原文地址:https://www.cnblogs.com/pruple/p/5477428.html
Copyright © 2020-2023  润新知