在 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 中的几个基础类 - 如 NSString
、NSArray
、NSNumber
- 表现得不像“正常”用户类。例如,NSNumber
通常是所谓的标记指针 - 指向“非法”地址(不能被 4 或 8 整除)的指针,表示值而不是地址。 NSString
, NSArray
... 被实现为所谓的类簇,这是一种在初始化器内部交换内部实现的机制(例如,返回一个不同的对象由 alloc
调用分配)。大多数情况下,NSString
是固定的/原子化的,这是一种通过简单的指针比较(而不是 strncmp
之类的逐字节比较)允许快速比较等的方法).
长话短说:您永远不应该依赖保留计数,这只是引用计数机制的一个实现细节。
关于ios内存管理出来这么乱 : CFGetRetainCount(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42674634/