在使用Xcode 14 Beta 5时,我在所有的obj-c项目中都遇到了这个新异常。 一些注意事项: - 异常出现在任何模拟器设备(运行iOS 16)上。 - 异常在
int main(int argc, char *argv[])
内的开头出现。
- 在运行iOS 15的真实设备上没有异常。
- 可以忽略异常(不会崩溃)。我想知道是否有其他人也遇到了这个问题。
int main(int argc, char *argv[])
内的开头出现。
- 在运行iOS 15的真实设备上没有异常。
- 可以忽略异常(不会崩溃)。Use a physical device: The issue doesn't occur when testing on a physical iOS device. I tested on an iPhone 13 Pro running iOS 16.0 with Xcode 14.0.1. The error doesn't occur then/there.
Ignore Objective-C exceptions: When the issue occurs, an Objective-C exception is thrown. Those are usually critical errors, but this particular exception is bogus. By default, Xcode always pauses the debugger when your app throws an Objective-C exception, but you can tell Xcode to stop doing that. In Xcode, go to the View --> Navigators --> Breakpoints menu. There, you'll see any/all breakpoints you have set. But one of the breakpoints appears there by default: "All Objective-C exceptions"; it has a dark blue arrow next to it, indicating that, yes, Xcode will indeed pause the debugger on all Objective-C exceptions.
If you click on that blue arrow, it will turn light blue, disabling the breakpoint. From then on, Xcode will ignore this exception, but, unfortunately, it will ignore all exceptions, even real exceptions that you actually care about. This may be enough to get you unstuck, but we'd normally want Xcode to pause on thrown exceptions (because they're normally very serious).
Add a condition to the "All Objective-C Exceptions" breakpoint: Since it's not great to just completely disable this breakpoint, we can do something cleverer. Enable the breakpoint (make sure its arrow is dark blue), then right-click on it and "Edit Breakpoint..." There, you can paste in this condition: !(BOOL)[(id)[$arg1 reason] containsString:@"_UINavigationBarContentViewLayout"]
That will cause the breakpoint to pause execution on all breakpoints except breakpoints that contain the string _UINavigationBarContentViewLayout
. Pretty good, I think! But every developer on your team will have to do this on every machine they use for testing. (Credit goes to Grigory Entin's comment)
Monkey-patch UINavigationBarContentViewLayout
: Objective-C is a dynamic language, allowing you to add methods to a class at
runtime. This is called monkey
patching. It's normally
unwise to do that, and it's normally especially unwise to do it to
Apple's code. Apple normally won't allow you to submit apps to the
store that monkey patch Apple's classes. But, as long as you're just
doing it on your machine, and just to workaround a bug in the Xcode
simulator, there's no harm in it, right?
The code sample here is based on a post from the Apple Developer Forum by moshiwu.
#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
Put that code at the top of your AppDelegate.m
file, and then, at the top of your - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
method, add this line: [Xcode14Fixer load];
moshiwu attempted to use #if DEBUG
to ensure that the code would only be used in debug mode, but that didn't work for me. Instead, just promise yourself that you'll remember to remove this debug code before you ship an official build to Apple, or Apple will probably reject your build.
objc_exception_throw
符号断点来解决它。希望这可以帮助到你。 - André Neves#if DEBUG
的解决方法可能很有用,直到苹果修复这个 bug(在 Xcode 14 RC 中仍然存在):https://developer.apple.com/forums/thread/712240?answerId=724164022#724164022 - Ortwin Gentz!(BOOL)[(id)[$arg1 reason] containsString:@"_UINavigationBarContentViewLayout"]
- Grigory Entin