ios内存管理出来这么乱 : CFGetRetainCount()

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

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

第一个代码片段:

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 输出让我感到困惑: 为什么第二个代码片段中的保留计数不是“1”?与第一个代码片段相比有什么不同吗?

最佳答案

问题在于 Objective C 中的几个基础类 - 如 NSStringNSArrayNSNumber - 表现得不像“正常”用户类。例如,NSNumber 通常是所谓的标记指针 - 指向“非法”地址(不能被 4 或 8 整除)的指针,表示值而不是地址。 NSString, NSArray... 被实现为所谓的类簇,这是一种在初始化器内部交换内部实现的机制(例如,返回一个不同的对象由 alloc 调用分配)。大多数情况下,NSString 是固定的/原子化的,这是一种通过简单的指针比较(而不是 strncmp 之类的逐字节比较)允许快速比较等的方法).

长话短说:您永远不应该依赖保留计数,这只是引用计数机制的一个实现细节。

关于ios内存管理出来这么乱 : CFGetRetainCount(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42674634/

相关文章:

ios - TestFlight App 安装但未在 TestFlight App Display 中显示已安装(TestFlight 显示已安装 90%)

ios - 是否可以在 swift 3 的 tableview 单元格中实现 tableview?

.net - .NET 业务层中的结构与类

memory-management - 黑莓内存管理

objective-c - 你能帮我理解添加到容器(NSDictionary、NSArray)时的 block 类型吗?

swift - 异步函数调用与无主对象的取消初始化发生冲突

objective-c - 自动引用计数是否会在运行时产生成本

ios - 导航栏标题字体颜色未使用 RGB 设置,但可以使用标准颜色

ios - 使用仪器了解给定时间发生的事件

c - 数组内存管理