0

我发现了 NSString 的内存泄漏objc_setAssociatedObject

测试代码:

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);。没有内存泄漏。

有谁知道发生了什么?

4

1 回答 1

1

可能与标记指针字符串有关

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

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

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

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

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

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

在此处输入图像描述

于 2020-05-28T15:05:52.263 回答