zoukankan      html  css  js  c++  java
  • iOS objectiveC retainCount, OC计数器的思考

    学OC,肯定知道内存管理机制的原则。这里说说某些特殊的情况。

    之前曾说,NSString的计数器比较特殊,大家注意下。

    今天说另外一种,也是比较纠结的,以至于朋友都说这是OC BUG。。。

    创建一个Class:

    //H
    #import <Foundation/Foundation.h>
    
    @interface Car : NSObject
    
    - (void)show;
    
    @end
    
    //M
    #import "Car.h"
    
    @implementation Car
    
    - (void)show;{
        NSLog(@"exec Finished!!!");
    }
    
    @end

    很简单的show方法,确认Car类是否被free;

    运行方法:

    Car *car = [[Car alloc] init];
    [car show];
    [car release];
    [car show];
    NSLog(@"car retainCount:%d", [car retainCount]);

    某些人可能一眼看出,执行未完成就会Crash;

    但事实是,毫无Crash征兆,并且retainCount printf 1;

    为什么会这样??经过与几个基友讨论,得出以下结论:

    1.car堆被标记,即release执行完成,但因为不是立即释放,所以内存还存在;

    2.存在栈中的car指针不由我们控制,同样未释放。

    所以,给car指针指向的那块内存发送show消息时,又得到了结果。

    既然不是OC的BUG,那如果避免?

    在我们的项目中,肯定不会出现这样的问题,因为当堆被标记,有新创建的OBJ,会自动占用掉。

    可以这样模拟:

    Car *car = [[Car alloc] init];
    [car show];
    [car release];
    for (int i = 0; i < 1000; i++) {
        @autoreleasepool {
            NSString *str = [NSString stringWithFormat:@"X%d", i];
            NSLog(@"%@", str);
        }
    }
    [car show];
    NSLog(@"%d", [car retainCount]);

    此时,不等运行到显示car的retainCount,已经Crash;

    符合我们的结论;

    如何避免就是大家熟悉的,在release后再设置nil即可;

    其他的内存方面就不说了,只说奇葩的部分!!不对的地方请指出,谢谢。

  • 相关阅读:
    【Java123】enum枚举及其应用
    sql查询优化_慢查询
    9.4 如何实现属性可修改的函数装饰器?
    9.2 如何为被装饰的函数保存元数据?
    python的如何通过实例方法名字的字符串调用方法?
    9.1 如何使用函数装饰器 用装饰器解决重复计算问题
    asyncio 笔记
    python笔记截图
    list绑定
    表单数据交互
  • 原文地址:https://www.cnblogs.com/maxfong/p/2977780.html
Copyright © 2011-2022 走看看