【问题标题】:Objective-C NSString memory leak with objc_setAssociatedObject带有 objc_setAssociatedObject 的 Objective-C NSString 内存泄漏
【发布时间】:2020-09-15 17:30:12
【问题描述】:

我发现objc_setAssociatedObject 的 NSString 存在内存泄漏

测试代码:

int i = 0;
while (YES) {
    @autoreleasepool {
        NSString *string = [[NSString alloc] initWithFormat:@"%d", i];
        // Comment this line. Then the memory leak is gone.
        objc_setAssociatedObject(string, "key", [[NSObject alloc] init], OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    }
    i++;
}

NSObject 无法释放。不确定NSString

如果我评论代码objc_setAssociatedObject(string, "key", [[NSObject alloc] init], OBJC_ASSOCIATION_RETAIN_NONATOMIC);。没有内存泄漏。

有人知道发生了什么吗?

【问题讨论】:

    标签: ios objective-c memory memory-leaks associated-object


    【解决方案1】:

    可能与Tagged Pointer Strings有关

    标记指针字符串实际上是无效的 64 位指针,其内容存储在指针本身中

    这有助于防止不必要的内存分配

    它们是无效指针,因为它们不指向任何实际内存值

    """对象在内存中对齐,这样它们的地址总是至少是指针大小的倍数,实际上通常是 16 的倍数。对象指针存储为一个完整的 64 位整数,但是这对齐意味着某些位将始终为零。

    标记指针利用这一事实为那些位不为零的对象指针赋予特殊含义。在 Apple 的 64 位 Objective-C 实现中,最低有效位设置为 1(即奇数)的对象指针被视为标记指针。接下来的三位被视为标记类表的索引,而不是执行标准的 isa 取消引用来计算类。该索引用于查找标记指针的类。剩下的 60 位则留给标记类随意使用。""" 这是一个漂亮的 hack。

    我认为 NSTaggedPointerString 的关联对象可能会在下一个运行循环中被清除

    【讨论】:

      猜你喜欢
      • 2016-09-05
      • 1970-01-01
      • 2015-06-20
      • 2011-03-17
      • 2011-06-07
      • 1970-01-01
      • 2011-10-31
      相关资源
      最近更新 更多