在视图之间转换时应用程序有时会崩溃:如何调试约束?
App crashing sometimes when transitioning between views: how to debug constraints?
我使用动画在视图之间执行转换。它有时有效,有时也会导致崩溃,我不明白为什么。我的代码在 @try-@catch
块中,但在 @catch
中没有检索到异常。我只是通过 SIGABRT 信号和以下日志收到应用程序崩溃:
2015-09-23 10:03:43.420 My App[1510:528283] The view hierarchy is not prepared for the constraint:
When added to a view, the constraint's items must be descendants of that view (or the view itself). This will crash if the constraint needs to be resolved before the view hierarchy is assembled. Break on -[UIView(UIConstraintBasedLayout) _viewHierarchyUnpreparedForConstraint:] to debug.
2015-09-23 10:03:43.421 My App[1510:528283] *** Assertion failure in -[UIView _layoutEngine_didAddLayoutConstraint:roundingAdjustment:mutuallyExclusiveConstraints:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit/UIKit-3505.16/NSLayoutConstraint_UIKitAdditions.m:590
我不明白为什么它有时可以工作有时会崩溃,我不明白我该如何调试它,我需要帮助。
提前致谢
编辑:
这似乎是导致应用程序崩溃的方法:
- (void)switchToMainView
{
[UIView transitionWithView:self.view
duration:1.0
options:UIViewAnimationOptionTransitionFlipFromRight
animations:^{
@try {
if ([self.secView superview]) {
[self setMainView];
[self.secView removeFromSuperview];
[self.view addSubview:self.mainView];
[self.view sendSubviewToBack:self.secView];
}
}
@catch (NSException *exception) {
NSLog(@"exception: %@", exception.description);
}
}
completion:^(BOOL finished){
if (finished) {
@try {
[self.view setNeedsUpdateConstraints];
[self setMessage];
}
@catch (NSException *exception) {
NSLog(@"exception: %@", exception.description);
}
}
}];
}
以及在完成块中调用的setMessage
方法:
- (void)setMessage
{
UIView *messageView = nil;
@try {
messageView = [[[NSBundle mainBundle] loadNibNamed:@"MessageView" owner:nil options:nil] firstObject];
messageView.frame = CGRectMake(0, 0, self.messagesContainerView.frame.size.width, self.messagesContainerView.frame.size.height);
[self.messagesContainerView.subviews makeObjectsPerformSelector: @selector(removeFromSuperview)];
[self.messagesContainerView addSubview:messageView];
}
@catch (NSException *exception) {
NSLog(@"exception: %@", exception.description);
}
}
其中 self.messagesContainerView
是第一种方法中 self.mainView
的子视图。
再次感谢
编辑 2:
这是我最后得到的崩溃信息:
Date/Time: 2015-09-24 10:01:13 +0000 OS Version: iPhone OS
9.0 (13A344) Report Version: 104
Exception Type: SIGABRT Exception Codes: #0 at 0x34de0d24 Crashed
Thread: 0
Application Specific Information:
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Impossible to set up
layout with view hierarchy unprepared for constraint.'
Last Exception Backtrace: 0 CoreFoundation
0x22ee786b 0x22df2000 + 1005675 1 libobjc.A.dylib
0x345e6dff 0x345e0000 + 28159 2 CoreFoundation
0x22ee7741 0x22df2000 + 1005377 3 Foundation
0x23c772ab 0x23be0000 + 619179 4 UIKit
0x277ced17 0x26fe7000 + 8289559 5 UIKit
0x270f8b1b 0x26fe7000 + 1121051 6 UIKit
0x270f898d 0x26fe7000 + 1120653 7 UIKit
0x270f88a7 0x26fe7000 + 1120423 8 UIKit
0x277cee6d 0x26fe7000 + 8289901 9 UIKit
0x270f878f 0x26fe7000 + 1120143 10 My App
0x000423c5 0x11000 + 201669 11 UIKit
0x277d479d 0x26fe7000 + 8312733 12 Foundation
0x23c29c81 0x23be0000 + 302209 13 UIKit
0x270fbaa9 0x26fe7000 + 1133225 14 UIKit
0x277d49d9 0x26fe7000 + 8313305 15 UIKit
0x270fc78b 0x26fe7000 + 1136523 16 Foundation
0x23c29c81 0x23be0000 + 302209 17 UIKit
0x270fbaa9 0x26fe7000 + 1133225 18 UIKit
0x270fc487 0x26fe7000 + 1135751 19 UIKit
0x277d4fa5 0x26fe7000 + 8314789 20 UIKit
0x272edfa9 0x26fe7000 + 3174313 21 UIKit
0x26ff56bb 0x26fe7000 + 59067 22 QuartzCore
0x268c167d 0x268b4000 + 54909 23 QuartzCore
0x268bcd79 0x268b4000 + 36217 24 QuartzCore
0x268bcc09 0x268b4000 + 35849 25 QuartzCore
0x268bc129 0x268b4000 + 33065 26 QuartzCore
0x268bbdeb 0x268b4000 + 32235 27 QuartzCore
0x268b55bf 0x268b4000 + 5567 28 CoreFoundation
0x22eaa0f1 0x22df2000 + 753905 29 CoreFoundation
0x22ea83e7 0x22df2000 + 746471 30 CoreFoundation
0x22ea8825 0x22df2000 + 747557 31 CoreFoundation
0x22dfb1e9 0x22df2000 + 37353 32 CoreFoundation
0x22dfafdd 0x22df2000 + 36829 33 GraphicsServices
0x2c09faf9 0x2c096000 + 39673 34 UIKit
0x2706018d 0x26fe7000 + 496013 35 My App
0x000d7d69 0x11000 + 814441 36 libdyld.dylib
0x34d11873 0x34d0f000 + 10355
Thread 0 Crashed: 0 libsystem_kernel.dylib 0x34de0d24
0x34dcc000 + 85284 1 libsystem_c.dylib 0x34d78f51
0x34d2e000 + 307025 2 My App 0x001abebf
0x11000 + 1683135 3 CoreFoundation 0x22ee7ba9
0x22df2000 + 1006505 4 libobjc.A.dylib
0x345e7087 0x345e0000 + 28807 5 libc++abi.dylib
0x33dcce17 0x33db6000 + 93719 6 libc++abi.dylib
0x33dcc8f7 0x33db6000 + 92407 7 libobjc.A.dylib
0x345e6f47 0x345e0000 + 28487 8 CoreFoundation
0x22dfb26f 0x22df2000 + 37487 9 CoreFoundation
0x22dfafdd 0x22df2000 + 36829 10 GraphicsServices
0x2c09faf9 0x2c096000 + 39673 11 UIKit
0x2706018d 0x26fe7000 + 496013 12 My App
0x000d7d69 0x11000 + 814441 13 libdyld.dylib
0x34d11873 0x34d0f000 + 10355
没有看到你的代码很难调试实际问题。可能的原因是:
- 您正在向不是受约束 class 的父视图的视图添加约束。
- 您正在向尚未添加为子视图的视图添加约束 - 因此不在视图层次结构中。
至于修复它。我设法创建了一个以这种方式崩溃的项目,并根据错误提示通过添加符号断点正确地发现了错误:
所以试试这个,看看你的问题是从哪里来的。
我使用动画在视图之间执行转换。它有时有效,有时也会导致崩溃,我不明白为什么。我的代码在 @try-@catch
块中,但在 @catch
中没有检索到异常。我只是通过 SIGABRT 信号和以下日志收到应用程序崩溃:
2015-09-23 10:03:43.420 My App[1510:528283] The view hierarchy is not prepared for the constraint: When added to a view, the constraint's items must be descendants of that view (or the view itself). This will crash if the constraint needs to be resolved before the view hierarchy is assembled. Break on -[UIView(UIConstraintBasedLayout) _viewHierarchyUnpreparedForConstraint:] to debug.
2015-09-23 10:03:43.421 My App[1510:528283] *** Assertion failure in -[UIView _layoutEngine_didAddLayoutConstraint:roundingAdjustment:mutuallyExclusiveConstraints:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit/UIKit-3505.16/NSLayoutConstraint_UIKitAdditions.m:590
我不明白为什么它有时可以工作有时会崩溃,我不明白我该如何调试它,我需要帮助。
提前致谢
编辑:
这似乎是导致应用程序崩溃的方法:
- (void)switchToMainView
{
[UIView transitionWithView:self.view
duration:1.0
options:UIViewAnimationOptionTransitionFlipFromRight
animations:^{
@try {
if ([self.secView superview]) {
[self setMainView];
[self.secView removeFromSuperview];
[self.view addSubview:self.mainView];
[self.view sendSubviewToBack:self.secView];
}
}
@catch (NSException *exception) {
NSLog(@"exception: %@", exception.description);
}
}
completion:^(BOOL finished){
if (finished) {
@try {
[self.view setNeedsUpdateConstraints];
[self setMessage];
}
@catch (NSException *exception) {
NSLog(@"exception: %@", exception.description);
}
}
}];
}
以及在完成块中调用的setMessage
方法:
- (void)setMessage
{
UIView *messageView = nil;
@try {
messageView = [[[NSBundle mainBundle] loadNibNamed:@"MessageView" owner:nil options:nil] firstObject];
messageView.frame = CGRectMake(0, 0, self.messagesContainerView.frame.size.width, self.messagesContainerView.frame.size.height);
[self.messagesContainerView.subviews makeObjectsPerformSelector: @selector(removeFromSuperview)];
[self.messagesContainerView addSubview:messageView];
}
@catch (NSException *exception) {
NSLog(@"exception: %@", exception.description);
}
}
其中 self.messagesContainerView
是第一种方法中 self.mainView
的子视图。
再次感谢
编辑 2:
这是我最后得到的崩溃信息:
Date/Time: 2015-09-24 10:01:13 +0000 OS Version: iPhone OS 9.0 (13A344) Report Version: 104
Exception Type: SIGABRT Exception Codes: #0 at 0x34de0d24 Crashed Thread: 0
Application Specific Information: *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Impossible to set up layout with view hierarchy unprepared for constraint.'
Last Exception Backtrace: 0 CoreFoundation
0x22ee786b 0x22df2000 + 1005675 1 libobjc.A.dylib
0x345e6dff 0x345e0000 + 28159 2 CoreFoundation
0x22ee7741 0x22df2000 + 1005377 3 Foundation
0x23c772ab 0x23be0000 + 619179 4 UIKit
0x277ced17 0x26fe7000 + 8289559 5 UIKit
0x270f8b1b 0x26fe7000 + 1121051 6 UIKit
0x270f898d 0x26fe7000 + 1120653 7 UIKit
0x270f88a7 0x26fe7000 + 1120423 8 UIKit
0x277cee6d 0x26fe7000 + 8289901 9 UIKit
0x270f878f 0x26fe7000 + 1120143 10 My App
0x000423c5 0x11000 + 201669 11 UIKit
0x277d479d 0x26fe7000 + 8312733 12 Foundation
0x23c29c81 0x23be0000 + 302209 13 UIKit
0x270fbaa9 0x26fe7000 + 1133225 14 UIKit
0x277d49d9 0x26fe7000 + 8313305 15 UIKit
0x270fc78b 0x26fe7000 + 1136523 16 Foundation
0x23c29c81 0x23be0000 + 302209 17 UIKit
0x270fbaa9 0x26fe7000 + 1133225 18 UIKit
0x270fc487 0x26fe7000 + 1135751 19 UIKit
0x277d4fa5 0x26fe7000 + 8314789 20 UIKit
0x272edfa9 0x26fe7000 + 3174313 21 UIKit
0x26ff56bb 0x26fe7000 + 59067 22 QuartzCore
0x268c167d 0x268b4000 + 54909 23 QuartzCore
0x268bcd79 0x268b4000 + 36217 24 QuartzCore
0x268bcc09 0x268b4000 + 35849 25 QuartzCore
0x268bc129 0x268b4000 + 33065 26 QuartzCore
0x268bbdeb 0x268b4000 + 32235 27 QuartzCore
0x268b55bf 0x268b4000 + 5567 28 CoreFoundation
0x22eaa0f1 0x22df2000 + 753905 29 CoreFoundation
0x22ea83e7 0x22df2000 + 746471 30 CoreFoundation
0x22ea8825 0x22df2000 + 747557 31 CoreFoundation
0x22dfb1e9 0x22df2000 + 37353 32 CoreFoundation
0x22dfafdd 0x22df2000 + 36829 33 GraphicsServices
0x2c09faf9 0x2c096000 + 39673 34 UIKit
0x2706018d 0x26fe7000 + 496013 35 My App
0x000d7d69 0x11000 + 814441 36 libdyld.dylib
0x34d11873 0x34d0f000 + 10355Thread 0 Crashed: 0 libsystem_kernel.dylib 0x34de0d24 0x34dcc000 + 85284 1 libsystem_c.dylib 0x34d78f51 0x34d2e000 + 307025 2 My App 0x001abebf 0x11000 + 1683135 3 CoreFoundation 0x22ee7ba9 0x22df2000 + 1006505 4 libobjc.A.dylib
0x345e7087 0x345e0000 + 28807 5 libc++abi.dylib
0x33dcce17 0x33db6000 + 93719 6 libc++abi.dylib
0x33dcc8f7 0x33db6000 + 92407 7 libobjc.A.dylib
0x345e6f47 0x345e0000 + 28487 8 CoreFoundation
0x22dfb26f 0x22df2000 + 37487 9 CoreFoundation
0x22dfafdd 0x22df2000 + 36829 10 GraphicsServices
0x2c09faf9 0x2c096000 + 39673 11 UIKit
0x2706018d 0x26fe7000 + 496013 12 My App
0x000d7d69 0x11000 + 814441 13 libdyld.dylib
0x34d11873 0x34d0f000 + 10355
没有看到你的代码很难调试实际问题。可能的原因是:
- 您正在向不是受约束 class 的父视图的视图添加约束。
- 您正在向尚未添加为子视图的视图添加约束 - 因此不在视图层次结构中。
至于修复它。我设法创建了一个以这种方式崩溃的项目,并根据错误提示通过添加符号断点正确地发现了错误:
所以试试这个,看看你的问题是从哪里来的。