__unsafe_unretained NSString struct var

Hur*_*rkS 3 iphone struct nsstring ios

我正在尝试创建一个结构,其中包含几个不同类型的不同变量.

有几种类型是NSString,但尝试这样做会导致错误

ARC forbids Objective-C objects in structs or unions

所以阅读有关错误,我认为添加是明智的

__unsafe_unretained
Run Code Online (Sandbox Code Playgroud)

在NSString声明之前,但我不知道这会产生什么后果,我已经快速阅读并发现了这篇关于差异的详细帖子

  • __强大
  • __弱
  • __unsafe_unretained

然而,在一个结构中使用了__unsafe_unretained并且希望有人可以告诉我发生了什么以及我将来需要考虑的关于内存和阻止任何泄漏的内容,这仍然是模糊的.

任何帮助,将不胜感激.

rob*_*off 10

假设,在ARC下,你可以声明一个这样的结构:

typedef struct {
    __strong NSObject *someObject;
    int someInteger;
} MyStruct;
Run Code Online (Sandbox Code Playgroud)

然后你可以写这样的代码:

MyStruct *thing = malloc(sizeof(MyStruct));
Run Code Online (Sandbox Code Playgroud)

问题:malloc不会将其返回的内存归零.所以thing->someObject是一些随机值 - 不一定是NULL.然后你给它分配一个值,如下所示:

thing->someObject = [[NSObject alloc] init];
Run Code Online (Sandbox Code Playgroud)

在封面下,ARC会将其转换为如下代码:

NSObject *temporary = [[NSObject alloc] init];
[thing->someObject release];
thing->someObject = temporary;
Run Code Online (Sandbox Code Playgroud)

这里的问题是你的程序只是发送release到一些随机值!您的应用可能会在此时崩溃.

您可能会说ARC应该识别调用malloc并注意设置someObject为NULL以防止这种情况.问题是malloc可能包含在其他一些函数中,如下所示:

void *myAllocate(size_t size) {
    void *p = malloc(size);
    if (!p) {
        // malloc failed.  Try to free up some memory.
        clearCaches();
        p = malloc(size);
    }
    return p;
}
Run Code Online (Sandbox Code Playgroud)

好的,现在ARC也必须知道你的myAllocate功能......这可能在你作为二进制文件获得的一些静态库中.

您的应用程序甚至可能有自己的内存分配器,无需使用freemalloc每次都可以回收旧的分配.所以即使malloc在返回之前更改为零填充内存也行不通.ARC必须知道程序中的任何自定义分配器.

要使这项工作可靠,将是非常非常困难的.相反,ARC的创造者只是放弃了并说"忘了它.我们不会让你在结构中放置__strong__weak引用."

这就是为什么你只能将一个对象指针放入一个结构中,如果你__unsafe_unretained用来告诉ARC"不要试图管理它引用的对象的所有权".

您可以尝试使用包含__unsafe_unretained对象引用的结构,可能使用CFRetainCFRelease手动保留和释放它们.然后,您可以创建此类结构的数组.这很容易出错,所以只有在探查器告诉您它对性能至关重要时才应该这样做.

相反,只需创建一个新的Objective-C类而不是结构.@property为每个要放在struct中的字段赋一个类.使用an NSMutableArray来管理这个新类的实例数组.