Xcode 8 Objective-C 类别警告

62

我正在使用Xcode 8和Swift 3.0。这个错误信息是什么意思?

ld: 警告: 一些目标文件具有不兼容的Objective-C类别定义。一些类别元数据可能会丢失。所有包含Objective-C类别的文件都应该使用相同的编译器构建。


请查看以下链接:https://github.com/Carthage/Carthage/issues/1482 和 https://forums.developer.apple.com/thread/49618 - Anbu.Karthik
谢谢。实际上在发帖之前我已经看过那些了,但是里面没有答案。 - jherg
你是否展开了警告消息?通常在该行的最右侧会有一个图标,可以展开消息并让您查看命令行调用和结果。 - Mobile Ben
@MobileBen 是的,谢谢。我在那里没有看到任何有用的东西。 - jherg
正如错误消息所提到的编译器版本(而且我假设您在升级到XCode 8之后进行了干净的构建):您是否在项目中使用任何以二进制形式(.a文件或第三方框架)提供的库? - Codo
2
刚拿到这个... 这里面没有一个能用的 :/ - William LeGate
8个回答

40

我在一个UIColor扩展中也遇到了这个问题,我的应用程序完全由Swift编写,除了一些使用Objective-c的框架以外,因此我可以毫无问题地将var声明为@nonobjc

extension UIColor {
   @nonobjc static var lol: UIColor {
      return UIColor.red
   }
}

来自苹果文档:

nonobjc 属性告诉编译器在 Objective-C 代码中使声明不可用...

由于此代码对Objective-C不可用,所以警告消失了。


4
我不得不在我的目标中使用的所有扩展中的所有类和静态变量上添加@nonobjc。只有这样警告才会消失。 - slamor
我试图使用正则表达式来查找所有具有静态属性的扩展,但是Xcode本身。 - RyanM

22
在我的情况下,原因是在扩展中存在计算类型属性:
extension NSParagraphStyle {
    class var defaultStyle: NSParagraphStyle {
        return ...
    }
}

不确定背后的确切原因是什么,但为了消除警告,我不得不将计算的类型属性 (class var) 转换为类型方法 (class func):

extension NSParagraphStyle {
    class func defaultStyle() -> NSParagraphStyle {
        return ...
    }
}

1
我正在尝试使用UIColor的扩展来创建自己的颜色集。它们必须是函数吗?在以前的Swift版本中,您可以使用UIColor.whiteColor(),但现在是UIColor.white。我想要有UIColor.myColor。有任何想法如何实现吗? - Olav Gausaker
如果您愿意,可以忽略警告,一切都应该正常工作。但是不确定您是否可以从ObjC代码中使用该属性。 - Hejazi
@Hejazi 有没有办法抑制这个警告?或者你所说的忽略警告是指假装看不见它? - Ismail
据我所知,在Swift中没有抑制警告的方法。我的意思是,你可以暂时忽略这个警告(直到苹果修复似乎是Swift编译器的错误),或者像我之前说的那样使用类型方法而不是计算类型属性。 - Hejazi
1
我看到了这个警告并找到了这个答案。我一开始很怀疑它对我是否有作用,因为警告似乎与答案无关,但是这个答案解决了警告。 - Josh Adams
这也是我的解决方案。我在Swift中声明了静态let/var属性,需要从Obj-C中访问(标记@nonobjc不是一个选项),所以我不得不将这些属性转换为静态函数。 - tylermilner

10

在我的应用程序中,添加一个使用Objective-C框架的项目后,出现了这个警告。我的应用程序本来完全使用Swift 3。

通过声明所有扩展中的所有静态函数和静态变量@nonobjc,此警告消失了。

例如:

extension Notification.Name {
    @nonobjc static let MyNotificationName = Notification.Name("NNSongFavoriteStatusDidChangeNotification")
}
或者
extension UIColor {
    @nonobjc static let superGiantRed = UIColor(red: 180.0/255.0, green: 40.0/255.0, blue: 27.0/255.0, alpha: 1.0)
}

9

Google Analytics Pod

如果在 构建设置 -> 其他链接标志中,您的-l"GoogleAnalytics"后面带有-ObjC标志,则会出现此警告。我不知道为什么或如何解决,但这也可能是您的问题。


1
@Raniys 我的朋友,我认为这个问题将在谷歌更新他们的存储库时得到解决。如果您删除 -ObjC 标志,则警告会消失,但我不知道这可能会对您的项目造成什么问题。 - Renato Ioshida
@Raniys 你好,我的朋友。我注意到在我的pod install之后出现了这个警告:“[!] The project[Debug] target overrides the ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES build setting defined in `podsFolder.xcconfig'. This can lead to problems with the CocoaPods installation"。当我在我的构建设置中纠正了这个警告之后,XCode的警告就消失了。 - Renato Ioshida

5
在我的情况下,它是一个类变量。
public extension NSObject {
    public class var nameOfClass: String{
        return NSStringFromClass(self).components(separatedBy: ".").last!
    }

加上 @nonobjc 就可以了。

4

我的问题是我在使用一个第三方框架,这个框架是由一个供应商使用Xcode 7构建的,而我的Swift 3应用是使用Xcode 8构建的。因为该框架是编译二进制文件,所以我唯一的选择是要求我的供应商提供一个使用最新版本的Xcode构建的新框架。


你能告诉我们它是哪个库吗? - allaire
@allaire 它是Adobe的专有SDK。 - JAL
啊,太糟糕了。我遇到了类似的问题,但是我没有动力一个一个地删除 pod :( - allaire
1
@allaire 这个问题只会在预构建的框架中出现。如果你有任何一个 CocoaPods 的源代码(这个 pod 是从源代码构建的),你可以把它们排除在外,因为你知道它们是使用你正在使用的最新版本的 Xcode 构建的。 - JAL
我怀疑Cocoapods中的静态库(例如Google Analytics)。 - allaire

1
我将我的问题解决了,当我把“class var”改成“class func”时: 原来是:
class var applicationVersionNumber: String {
    if let version = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String {
        return version
    }
    return "Version Number Not Available"
}

已经变成:
class func applicationVersionNumber() -> String {
    if let version = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String {
        return version
    }
    return "Version Number Not Available"
}

来源:https://forums.developer.apple.com/message/146579#146579


0

不必逐个标记每个成员为@nonobjc,您可以将整个扩展标记为@nonobjc

@nonobjc extension UIStoryboard {
  static let main = UIStoryboard(name: "Main", bundle: nil)
  static let welcome = UIStoryboard(name: "Main", bundle: nil)
}

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