zoukankan      html  css  js  c++  java
  • NSArray是强引用容器

    经常比较疑惑NSArray、NSDictionary、NSSet这几个对象容器管理对象所采用的方式是“强引用”还是“弱引用”。

    通过简单的命令行程序得到的结论是“NSArray、NSDictionary、NSSet这几个容器都是强引用容器”。

    打开Xcode,新建project,选择“OS X”-“Application”-“Command Line Tool”,完成project的创建,默认情况下,project会使用ARC,这里不需要使用ARC,所以还需要在project配置文件中将ARC取消。容易在“PROJECT”-“Build Settings”-“Apple LLVM 6.0 - Language - Objective C”中找到“Objective-C Automatic Reference Counting”这一项,选择为“No”即可。

    话不多说,开始。

    创建一个类Person,该类定义很简单,只有一个name属性:

    @interface Person : NSObject
        
    @property (nonatomic, retain) NSString *name;
        
    @end

    main.m文件代码如下:

    int main(int argc, const char * argv[]) {
        
        Person *person = [[Person alloc] init];
        person.name = @"Jason";
        
        NSLog(@"(1). Object Reference Count = %lu, name=%@",
              [person retainCount], person.name);
        // output: (1). Object Reference Count = 1, name=Jason
        
        NSArray *array = @[person];
        NSLog(@"(2). Object Reference Count = %lu, name=%@",
              [person retainCount], person.name);
        // output: (2). Object Reference Count = 2, name=Jason
        
        [array release];
        NSLog(@"(3). Object Reference Count = %lu, name=%@",
              [person retainCount], person.name);
        // output: (3). Object Reference Count = 1, name=Jason
        
        [person release];
        NSLog(@"(4). Object Reference Count = %lu, name=%@",
              [person retainCount], person.name);
        // output: (4). Object Reference Count = 1, name=Jason
        
        return 0;
    }

    刚开始对output(4)的输出非常不理解,有两个疑点: 

    1. [person release]之后person对象应该不存在了,为什么其reference count为1而不是0呢?
    2. person不是被released了吗,为什么还能访问器name属性?

    对于第一个问题,读了唐巧的《iOS开发进阶》,得出的答案是:
    因为该对象已经被回收,而我们向一个被回收的对象发了一个retainCount消息,所以它的输出结果应该是不确定的。那为什么在这个对象被回收之后,这个不确定的值是1而不是0呢?这是因为当最后一次执行release时,系统知道马上就要回收内存了,就没有必要再将retainCount减1了,因为不管减不减1,该对象肯定会被回收,而对象被回收后,它的所有内存区域,包括retainCount值也变得没有意义了。不将这个值从1变为0,可以减少一次内存的操作,加速对象的回收。

    对于第二个问题,还没有找到比较权威的解释,以后再来回到吧。

    总之,搞清楚了“NSArray、NSDictionary以及NSSet都是强引用容器”这个事实。

  • 相关阅读:
    85 容器(十二)——队列与栈:LinkedList的光芒万丈
    84 关于数据结构中的添加与取出的方法:push pop poll offer add get...
    83 lambda表达式
    82 subList()方法于asList()的細節以及UnsupportedOperationException
    81 Javaassist——class文件的操作
    80 脚本引擎——js脚本引擎
    03 NoClassDefFoundError
    79 动态编译与动态运行
    78 反射——概念、类的各种信息的获取(类名,属性,方法...)
    002 为什么接口中可以同时使用public与default 修饰抽象方法?
  • 原文地址:https://www.cnblogs.com/FightingLuoYin/p/4521819.html
Copyright © 2011-2022 走看看