Xcode 14 Beta 5 抛出异常

Jos*_*hua 7 beta xcode exception xcode14

Xcode 14 Beta 5 显示此异常:

[<_UINavigationBarContentViewLayout valueForUndefinedKey:]: this class is not key value coding-compliant for the key inlineTitleView.

使用 Xcode 14 Beta 5 时,我在所有 obj-c 项目中都遇到了这个新异常。

一些注意事项:

  • 任何模拟器设备上都会出现异常(运行 iOS 16)
  • 异常出现在里面的开头int main(int argc, char * argv[])
  • 在运行 iOS 15 的真机上也不例外
  • 异常可以被忽略(不会崩溃)。

我想知道是否还有其他人遇到过这种情况。

Dan*_*ich 5

这是 Xcode 14 中的一个错误。其他用户已在此报告: https: //developer.apple.com/forums/thread/712240

最初,该问题是在 Xcode 14 beta 中报告的,但该错误从未得到修复,现在,我们就到了。我在 Xcode 14.0.1 的正式版本中重现了该问题。

以下是我已经测试过的可行的解决方法:

  1. 使用物理设备:在物理 iOS 设备上测试时不会出现此问题。我在运行 iOS 16.0 和 Xcode 14.0.1 的 iPhone 13 Pro 上进行了测试。该错误不会在那时/那里发生。

  2. 忽略 Objective-C 异常:当问题发生时,会抛出 Objective-C 异常。这些通常是严重错误,但这个特殊的例外是伪造的。默认情况下,当您的应用程序引发 Objective-C 异常时,Xcode 始终会暂停调试器,但您可以告诉 Xcode 停止这样做。在 Xcode 中,转到“视图”->“导航器”->“断点”菜单。在那里,您将看到您设置的任何/所有断点。但默认情况下,断点之一会出现在此处:“所有 Objective-C 异常”;它旁边有一个深蓝色箭头,表明 Xcode 确实会在所有 Objective-C 异常上暂停调试器。

    “所有 Objective-C 异常”断点

    如果单击该蓝色箭头,它将变成浅蓝色,从而禁用断点。从那时起,Xcode将忽略这个异常,但不幸的是,它将忽略所有异常,甚至是你真正关心的真正异常。这可能足以让您摆脱困境,但我们通常希望 Xcode 在抛出异常时暂停(因为它们通常非常严重)。

  3. 向“所有 Objective-C 异常”断点添加一个条件:由于完全禁用此断点并不好,因此我们可以做一些更聪明的事情。启用断点(确保其箭头为深蓝色),然后右键单击它并“编辑断点...”,您可以在其中粘贴以下条件:!(BOOL)[(id)[$arg1 reason] containsString:@"_UINavigationBarContentViewLayout"]这将导致断点在以下断点之外的所有断点上暂停执行:包含字符串_UINavigationBarContentViewLayout. 我觉得还不错!但是团队中的每个开发人员都必须在他们用于测试的每台机器上执行此操作。(归功于Grigory Entin 的评论

  4. Monkey-patch UINavigationBarContentViewLayout Objective-C 是一种动态语言,允许您在运行时向类添加方法。这称为猴子修补。这样做通常是不明智的,尤其是对苹果的代码这样做尤其不明智。Apple 通常不会允许您向商店提交对 Apple 类进行修补的应用程序。但是,只要您只是在自己的计算机上执行此操作,并且只是为了解决 Xcode 模拟器中的错误,就没有什么坏处,对吗?

    此处的代码示例基于moshiwu 在 Apple 开发者论坛上发表的帖子

    #import <objc/runtime.h>
    
    @interface Xcode14Fixer : NSObject
    @end
    
    @implementation Xcode14Fixer
    
    + (void)load
    {
        Class cls = NSClassFromString(@"_UINavigationBarContentViewLayout");
        SEL selector = @selector(valueForUndefinedKey:);
        Method impMethod = class_getInstanceMethod([self class], selector);
    
        if (impMethod) {
            class_addMethod(cls, selector, method_getImplementation(impMethod), method_getTypeEncoding(impMethod));
        }
    }
    
    - (id)valueForUndefinedKey:(NSString *)key
    {
        return nil;
    }
    
    @end
    
    Run Code Online (Sandbox Code Playgroud)

    将该代码放在文件的顶部AppDelegate.m,然后在方法的顶部- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {添加以下行:[Xcode14Fixer load];

    moshiwu 尝试使用#if DEBUG来确保代码仅在调试模式下使用,但这对我不起作用。相反,只需向自己保证,在将正式版本发送给 Apple 之前,您会记得删除此调试代码,否则 Apple 可能会拒绝您的版本。