我正在尝试创建一个结构,其中包含几个不同类型的变量。
有几种类型是NSString的,但是尝试这样做会导致错误。
ARC forbids Objective-C objects in structs or unions
因此,在阅读了关于错误的文章后,我认为增加
__unsafe_unretained然而,在NSString声明之前,我不知道这会产生什么后果,我已经快速阅读了一下,并发现了关于
然而,对于一个NSString的结构中的__unsafe_unretained信息,它仍然含糊不清,并且希望有人能告诉我发生了什么,以及我在未来需要考虑的关于内存和阻止任何泄漏的事情。
任何帮助都将不胜感激。
发布于 2012-08-08 04:23:58
假设,在ARC下,您可以声明如下结构:
typedef struct {
__strong NSObject *someObject;
int someInteger;
} MyStruct;然后,您可以编写如下代码:
MyStruct *thing = malloc(sizeof(MyStruct));问题:malloc没有零填充它返回的内存。因此,thing->someObject是一些随机值-不一定为空。然后给它赋值如下:
thing->someObject = [[NSObject alloc] init];在封面下,ARC将将其转换为如下代码:
NSObject *temporary = [[NSObject alloc] init];
[thing->someObject release];
thing->someObject = temporary;这里的问题是,您的程序刚刚将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;
}好吧,现在ARC也要知道你的myAllocate函数.这可能是在一些静态库中得到的二进制文件。
您的应用程序甚至可能有自己的内存分配器,无需每次使用free和malloc就可以回收旧分配。因此,即使在返回之前将malloc更改为零填充内存也不起作用。在你的程序中,弧必须知道任何定制的分配器。
要使这项工作可靠地进行是非常非常困难的。相反,ARC的创建者放弃了,说:“算了吧。我们不会让您将__strong和__weak引用放在结构中。“
这就是为什么只有在使用__unsafe_unretained告诉ARC“不要试图管理它引用的对象的所有权”时,才能将对象指针放入结构中。
您可以尝试使用包含__unsafe_unretained对象引用的结构,也许可以使用CFRetain和CFRelease手动保留和释放它们。然后,您可以创建这样的结构数组。这很容易出错,所以只有当分析器告诉您它对性能至关重要时,您才应该这样做。
相反,只创建一个新的Objective类,而不是一个struct。为类提供一个@property,用于您在结构中放入的每个字段。使用NSMutableArray管理这个新类的实例数组。
发布于 2012-08-08 04:47:35
只是更多的思考..。
如果您确实需要非目标-c代码中的ARC指针,则可以在C++中使用它们。
实际上,您可以将ARC指针存储在所有标准模板容器中,并且它们仍然保留( ha )正确的语义。
struct Foo {
NSDictionary *dictionary;
NSString *string;
__weak UIViewController *viewController;
};
std::list<UIView*> views;由于编译器将ARC指针视为具有非平凡构造函数的对象,因此它们可以具有正常的语义。
他们所有的ARC荣耀都会被魔法处理。
发布于 2012-08-08 03:51:49
只是喜欢抱怨!事实上,我们必须从历史的角度来看待这个问题。在旧风格的手册参考计数环境中,编译器没有抱怨,因为它知道所有与内存相关的东西都将是您的工作,而您的工作则是单独的。但当苹果引入自动引用计数时,这种情况发生了变化,因为编译器需要更多地分析对象的类型和包含在其中的内容,这样才能知道如何有效地管理所述对象的内存。当你把一个目标-C对象放到一个C-结构中时,你就像是在向编译器伸出你的舌头,因为一个结构意味着你将自己拥有和管理它里面的项目的内存(这和ARC不接触malloc和free)。这就是__unsafe_unretained进来的原因。使用它,我们告诉编译器,任何和所有内存操作都是您的责任,就像在MRC中一样。圆弧字面上“不能保证”对象的指针在取消分配后为零的安全性,因此它使您显式地声明了它本身。
如果您想避免所有这些无稽之谈,只需使您的结构成为一个轻量级类,并声明您的对象正常。毕竟,Objective中的类只是C-结构-(Ish),有很多苹果的魔力。
https://stackoverflow.com/questions/11857117
复制相似问题