Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c Swift是否与弧前目标C不兼容?_Objective C_Automatic Ref Counting_Swift - Fatal编程技术网

Objective c Swift是否与弧前目标C不兼容?

Objective c Swift是否与弧前目标C不兼容?,objective-c,automatic-ref-counting,swift,Objective C,Automatic Ref Counting,Swift,我开始将Swift文件添加到一个非常大的遗留Objective-C项目中,该项目不使用ARC 编译项目时,我会收到ProjectName Swift.h桥头中发出的每个属性的警告: 未指定“分配”、“保留”或“复制”属性-假定为“分配” 默认属性“assign”不适用于非GC对象 斯威夫特似乎正在发射基于电弧的Objective-C代码 这是Swift特定版本中的一个限制/缺陷,还是Swift仅设计用于ARC代码?您可以混合使用ARC和非ARC代码。ARC编译的代码所做的就是自动向用户管理其

我开始将Swift文件添加到一个非常大的遗留Objective-C项目中,该项目不使用ARC

编译项目时,我会收到
ProjectName Swift.h
桥头中发出的每个属性的警告:

  • 未指定“分配”、“保留”或“复制”属性-假定为“分配”
  • 默认属性“assign”不适用于非GC对象
斯威夫特似乎正在发射基于电弧的Objective-C代码


这是Swift特定版本中的一个限制/缺陷,还是Swift仅设计用于ARC代码?

您可以混合使用ARC和非ARC代码。ARC编译的代码所做的就是自动向用户管理其内存。您应该为项目启用ARC,然后使用
-fno objc ARC
禁用单个文件的ARC,或者使用
-fobjc ARC
仅为Swift文件启用ARC(这可能不是必需的,因为编译器可能会自动添加它)。Swift代码最终编译为使用相同的Objective C运行时,编译器插入的ARC调用与Objective C中的调用相同。编译后,ARC和非ARC代码的行为相同

编译项目时,我会收到ProjectName Swift.h桥头中发出的每个属性的警告


一旦我将所有文件转换为ARC,我就能够消除警告。(不使用
-fno objc arc

Swift为Obj-C生成的头文件似乎假定arc正在您的Obj-C代码中使用。根据您的Xcode版本和生成设置,您可能会启用一个警告,每当属性隐式地为
分配
-属性时,该警告会向您发出警告,这仅在非ARC代码中是如此,在ARC代码中,属性隐式地为
strong
(与非ARC代码中的
保留
完全相同)。启用该警告后,每次将生成的头导入非ARC且Swift未为该属性设置存储属性的.m文件时,都会收到该警告

但是这个警告并不意味着编译后的代码以后不能正常工作。尽管编译器认为该属性只是
assign
,但它肯定不是
assign
,因为Swift属性甚至不能
assign
,它们可以是
strong
,也可以是
弱的
分配
-当对象死亡时,属性变为
分配
-属性变为悬空指针,仍然指向对象曾经生存的地址)。尽管有警告,但这可能导致的最糟糕的情况是静态代码分析器结果不正确,因为分析器可能还会警告您此
assign
-属性如何破坏您的代码,并且再次警告,分析器是错误的,因为简单属性实际上不是
assign

要解决这个问题,唯一需要做的就是永远不要依赖于默认情况下的任何属性,始终正确地将所有属性标记为
strong
,这也适用于非ARC代码(
strong
retain
只是编译器的同义词,它对两者的处理完全相同,因此两者都可以在非ARC代码中使用)。有趣的是,Swift通常就是这么做的。我在生成的头中有大量的
strong
属性,但显然有些情况下Swift不会这么做(也许这实际上是一个快速的错误)

解决该问题的简单方法是在导入生成的标题时禁用警告,具体操作如下:

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wobjc-property-no-attribute"
#import "xxx-Swift.h"
#pragma clang diagnostic pop
只需将其打包到另一个头文件中,例如
My xxx Swift.h
,然后只导入
My xxx Swift.h


我不会在整个项目中禁用它(例如,在Xcode构建设置中)通常情况下,此警告非常有意义,在混合ARC和非ARC代码时有助于防止可怕的错误,因为属性可能没有您认为它具有的存储属性,因此在混合ARC和非ARC时,强烈建议您永远不要依赖隐式属性,并始终使存储显式。

我不知道你为什么还没有使用ARC。我知道这是遗留代码,但遗留代码应该更新…在“预ARC”时代被称为
MRC
,也许知道你在使用什么是好的。@LordZsolt是为了避免在一个大型代码库中不必要地引入内存管理错误,这个代码库在ARC之前的内存管理制度下已经过很好的测试。@holex我认为它最好被称为
MRR
@LordZsolt不是每个人都喜欢ARC。首先,ARC语法很麻烦,更糟糕的是,一个强大的
self
指针隐含在块中(导致保留循环)。您编写的所有内容都是正确的,但与问题无关。问题不是“在”之后,而是“在编译时”当编译器读取头文件时,Swift生成的头文件始终采用ARC,因此如果在非ARC类中使用该头文件,则编译后对象的行为将正确,没有问题,但编译器将发出警告,因为对于导入此头文件的非ARC文件,头文件不正确,我担心就是这样,我也找不到任何解决方案。什么是“不正确”的平均值?您是指ARC指定的修饰符,例如
?如果属性没有存储属性,则在非ARC中为
分配
,但在ARC中为
保留
/
,因此,如果要在ARC和非ARC Obj-C文件中使用相同的头文件,则必须始终使用显式存储属性,否则编译器将一度认为这是一个
assign
属性,并且一度认为这是一个
strong
属性,但实际上,它只能是一个,所以是一个假设