提问人:Joshua 提问时间:8/14/2022 最后编辑:WillekeJoshua 更新时间:10/18/2022 访问量:809
Xcode 14 Beta 5 抛出异常
Xcode 14 Beta 5 throws an exception
问:
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 的真实设备上也不例外
- 可以忽略异常(无崩溃)。
我想知道是否有其他人遇到过这种情况。
答:
这是 Xcode 14 中的一个错误。其他用户在这里报告了它: https://developer.apple.com/forums/thread/712240
最初,该问题在 Xcode 14 测试版中报告,但该错误从未修复,现在,我们来了。我在 Xcode 14.0.1 的官方版本中重现了该问题。
以下是我测试过的有效解决方法:
使用物理设备:在物理 iOS 设备上进行测试时,不会出现此问题。我在运行 iOS 16.0 和 Xcode 14.0.1 的 iPhone 13 Pro 上进行了测试。错误不会在当时/那里发生。
忽略 Objective-C 异常:发生问题时,将引发 Objective-C 异常。这些通常是严重错误,但这个特定的例外是虚假的。默认情况下,当 App 引发 Objective-C 异常时,Xcode 始终会暂停调试器,但您可以告诉 Xcode 停止这样做。在 Xcode 中,转到“视图”-“>导航器”--“>断点”菜单。在那里,你将看到你设置的任何/所有断点。但默认情况下,其中一个断点会出现在那里:“所有 Objective-C 异常”;它旁边有一个深蓝色的箭头,表示是的,Xcode 确实会在所有 Objective-C 异常时暂停调试器。
如果单击该蓝色箭头,它将变为浅蓝色,从而禁用断点。从那时起,Xcode 将忽略此异常,但不幸的是,它将忽略所有异常,甚至是您真正关心的真正异常。这可能足以让你摆脱困境,但我们通常希望 Xcode 在抛出异常时暂停(因为它们通常非常严重)。
在“All Objective-C Exceptions”断点添加一个条件:由于完全禁用此断点不是很好,我们可以做一些更聪明的事情。启用断点(确保其箭头为深蓝色),然后右键单击它并“编辑断点...”在那里,您可以粘贴以下条件: 这将导致断点暂停所有断点的执行,但包含字符串的断点除外。相当不错,我想!但是,团队中的每个开发人员都必须在他们用于测试的每台计算机上执行此操作。(归功于 Grigory Entin 的评论
!(BOOL)[(id)[$arg1 reason] containsString:@"_UINavigationBarContentViewLayout"]
_UINavigationBarContentViewLayout
)猴子补丁
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
将该代码放在文件的顶部,然后在方法的顶部添加以下行:
AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[Xcode14Fixer load];
Moshiwu 试图使用以确保代码仅在调试模式下使用,但这对我不起作用。相反,只需向自己保证,在向 Apple 发布正式版本之前,您会记得删除此调试代码,否则 Apple 可能会拒绝您的版本。
#if DEBUG
评论
objc_exception_throw
#if DEBUG
!(BOOL)[(id)[$arg1 reason] containsString:@"_UINavigationBarContentViewLayout"]