我有一个大型应用程序,其中包含我们多年来编写的大量 ObjC 类。我正在尝试一次迁移到 Swift,因为我不能冒险进行可能会破坏太多东西的大规模迁移。
这是我当前问题的类层次结构:
OverFreeAnimalLimitViewController.swift (was originally ObjC) ->
FixBillingIssueViewController.swift (was originally ObjC) ->
BaseViewController.m ->
UIViewController
BaseViewController.m
具有:
@property(nullable, strong, nonatomic) IBOutletCollection(UIButton) NSArray<UIButton*> *appstring_buttons;
在 Storyboard中,我将所有按钮附加到该集合,以便我可以通过编程方式设置它们的所有样式,而不必在 Storyboard中一遍又一遍地执行相同的配置。
Storyboard中的底层 xml 代码如下所示:
<connections>
<outletCollection property="appstring_buttons" destination="Kwf-Mv-Gis" id="ZzW-k6-Ydm"/>
<outletCollection property="appstring_buttons" destination="f7s-5H-81g" id="xRb-XN-pNs"/>
</connections>
当OverFreeAnimalLimitViewController
和FixBillingIssueViewController
用objc编写时,这可以正常工作。
我已将它们转换为 swift,现在应用程序在处理 Storyboard时崩溃。当我运行应用程序并且 Storyboard尝试附加所有 socket 和 socket 集合时,我得到:
'NSUnknownKeyException', reason: '[<UIViewController 0x12b662370> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key appstring_buttons.'
我注意到错误消息显示的是 UIViewController
而不是 OverFreeAnimalLimitViewController
,因此我检查了 Storyboard, Storyboard正确地将自定义类列为 OverFreeAnimalLimitViewController
对于这个 View Controller 。
我发现 swift 只有 @IBOutlet
并且没有明确地具有 @IBOutletCollection
因为当你想使用集合时,你只需使用数组类型使用 @IBOutlet 注释。但这是否意味着如果它尝试使用底层 @IBOutletCollection
就会严重崩溃?
在 OverFreeAnimalLimitViewController.swift
中,如果我尝试编写代码来引用 self.appstring_buttons
,Xcode 将为我提供此自动完成功能:
有没有办法解决这个问题,或者无法使用从带有 @IBOutletCollections 的 ObjC 类扩展的 Swift 类?
最佳答案
好吧,我明白了。它与 Storyboard 的内部结构有关,而不是与 IBOutletCollection
有关。定义。
我在 Xcode 中创建了一个全新的项目来测试这个问题,并且 socket 集合按预期工作,所以我知道这不是一个错误,并且应该有一个适合我的实际项目的正确解决方案。
一直困扰我的一件事是错误消息显示 [<UIViewController 0x12b662370> setValue:forUndefinedKey:]
与 UIViewController
而不是OverFreeAnimalLimitViewController
。当我在问题一开始就看到这个问题时,我立即检查了 Storyboard以确保自定义类已设置,因为它看起来只是加载了一个裸露的 UIViewController 而不是我的子类。但我检查了一下,它是在 Storyboard 中设置的,所以我认为这是问题所在。
修复了什么
我进入 Storyboard并清除了自定义类设置,以便它回到标准的 UIViewController。然后我设置OverFreeAnimalLimitViewController
再次作为自定义类。然后就成功了。
看起来是这样的,当 Xcode 设置自定义类时,它会查找引用的类,当它发现它是一个 swift 类时,它会向 Storyboard添加一些额外的属性,即 customModule
和customModuleProvider
这将允许它加载正确的类。
<viewController customClass="OverFreeAnimalLimitViewController" title="subscribe_to_sync" id="CMN-i2-ISu" sceneMemberID="viewController">
<viewController customClass="OverFreeAnimalLimitViewController" customModule="HerdBoss" customModuleProvider="target" title="subscribe_to_sync" id="CMN-i2-ISu" sceneMemberID="viewController">
之后,它能够加载正确的 View Controller 子类,然后正确连接 socket 。
关于ios - 在使用 @IBOutletCollection 扩展 ObjC 子类的 Swift 类中不符合键值编码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74396056/