Ios内存管理如此困惑:CFGetRetainCount()

时间:2017-03-08 14:56:07

标签: ios memory-management automatic-ref-counting dynamic-arrays retaincount

在ARC环境中,我分配一个动态数组,其中每个元素都是指向NSObject *的指针。然后使用CFGetRetainCount获取NSObject的保留计数。结果如预期的那样出现。但是,当我将NSObject更改为NSString时,保留计数会出现一个很大的数字,这让我很困惑。我搜索了谷歌,但无法找到任何有价值的信息。那么,谁能解释一下?感谢任何帮助。

第一段代码:

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        NSObject* __strong *arr = nil;
        arr = (id __strong *)calloc(2, sizeof(id));
        *arr = [[NSObject alloc]init];
        *(arr + 1) = [[NSObject alloc]init];
        NSLog(@"--->retainCount:%lu -->%@", CFGetRetainCount((__bridge CFTypeRef)*arr), *arr);
        //output:--->retainCount:1 --><NSObject: 0x100103a00>
        *arr = nil;
        *(arr + 1) = nil;
        free(arr);
    }
    return 0;
}

第二段代码:

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        NSString* __strong *arr = nil;
        arr = (id __strong *)calloc(2, sizeof(id));
        *arr = [[NSString alloc]initWithString:@"str_01"];
        *(arr + 1) = [[NSString alloc]init];
        NSLog(@"--->retainCount:%lu \n-->%@", CFGetRetainCount((__bridge CFTypeRef)*arr), *arr);
        //output:--->retainCount:1152921504606846975 -->str_01
        *arr = nil;
        *(arr + 1) = nil;
        free(arr);
    }
    return 0;
}

NSLog输出混淆了我: 为什么保留计数不是&#34; 1&#34;在第二个代码片段?与第一个代码片段相比有什么不同吗?

1 个答案:

答案 0 :(得分:1)

问题在于,目标C中的几个基础课程 - 如NSStringNSArrayNSNumber - 表现得不像#34;正常&#34;用户类。例如,NSNumber通常是所谓的标记指针 - 指向&#34;非法&#34;地址(不能被4或8整除)并表示值而不是地址。 NSStringNSArray ...被实现为所谓的类集群,这是一种在初始化程序内部交换内部实现的机制(例如,返回与{分配的对象不同的对象)。 {1}}致电)。大多数情况下,alloc被实习/雾化,这是一种允许通过简单的指针比较(而不是NSString进行快速比较等的方式 - 比如逐字节比较)。

简而言之:您永远不应该依赖保留计数,这只是引用计数机制的实现细节。