ARC禁止在结构体或联合体中使用Objective-C对象,即使将文件标记为-fno-objc-arc。

85
为什么即使标记了-fno-objc-arc,ARC 仍禁止在结构体或联合体中使用 Objective-C 对象?
我之前的假设是如果你标记了 -fno-objc-arc,就不会有这个限制。
4个回答

169
如果你收到了这个信息,请尝试使用__unsafe_unretained。只有在结构体中的对象是未保留的情况下才安全。例如:如果你在ARC中使用OpenFeint,OFBragDelegateStrings类会在结构体中显示此错误。
typedef struct OFBragDelegateStrings
{
     NSString* prepopulatedText;
     NSString* originalMessage;
} OFBragDelegateStrings;
我很高兴能担任您的翻译。以下是您需要翻译的内容:

to

typedef struct OFBragDelegateStrings
{
     __unsafe_unretained NSString* prepopulatedText;
     __unsafe_unretained NSString* originalMessage;
} OFBragDelegateStrings;

4
当我分配字符串时,它显示警告:“将保留的对象分配给不安全的未保留变量对象,在赋值后将释放该对象。”当我使用它时,它会崩溃。 - Deepak Singh Negi
8
这并不能解决所有问题,对象通常会立即被释放,因此无法使用。 - Diziet
是的 - 这实际上并不起作用...解决方案是以某种方式关闭派生源文件的ARC,但我还没有能够弄清楚... - nielsbot
1
你可以在构建阶段的文件中添加-fno-objc-arc标志来实现这一点。 - Abizern
如果结构体字段只是一个“无用引用”,而对象实际上被保留(拥有)在其他地方(比如,在NSArray内部),那么它不会立即被释放,但我想知道编译器会说什么(现在无法测试)... - Nicolas Miari

30

与使用struct不同,你可以创建一个Objective-C类来管理数据。


怎么样?示例在哪里? - user285594
1
那么为什么对于小型用例来说不能使用结构体呢? - Devanshu Saini

13

那是因为arc无法跟踪结构体或联合体中的对象(因为它们在此时是普通的C指针)。

即使你使用-fno-objc-arc标记了相关的文件/类,你仍然可能将由arc控制的对象作为参数传递给它,这很可能会导致内存泄漏。


但是我如何能够在我的项目中同时使用 ARC 和非 ARC 文件呢?例如,我使用 ShareKit 作为非 ARC 文件,我可以使用实例进行发布。而我正在使用的文件是 ARC 文件。 - Zsolt
你可以在项目中使用-fno-objc-arc混合ARC和非ARC文件,但如果你在任何地方使用普通的C结构体,比如struct或union,就不能使用ARC。 - voidStern
感谢voidStern的回答。"但是如果你在任何地方使用普通的C结构,比如struct或union,你就不能使用ARC。" - 我不认为这是正确的。我正在我的文件中使用ARC。而对于libharu文件,我使用非ARC。我解决原始问题的方法是将值分别传递给C文件,并在那里创建结构体。我认为关键是从ARC到非ARC再到ARC的跳转。 - Zsolt
1
可能有点夸张。实际上,您不能将指向对象的指针放入结构体和联合体中,这会使ARC混淆。使用带有结构体和/或联合体的纯C库应该是(通常)可行的。 - voidStern

8
看起来现在没有错误了,很可能是由于这个更改之后。也就是说,您可以将普通(强)指针放入C结构中的Objective-C对象中。它由ARC管理,例如,当结构被销毁时,它不会被保留。已验证:$ clang --version Apple LLVM version 10.0.0 (clang-1000.11.45.2)

2
LLVM的最新动态 - WWDC 2018 - Míng

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接