UIViewAlertForUnsatisfiableConstraints를 잡는 방법?


234

디버거 로그에 오류가 나타납니다.

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x191f0920 H:[MPKnockoutButton:0x17a876b0]-(34)-[MPDetailSlider:0x17a8bc50](LTR)>

Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.

그 전화를 어떻게 잡을 수 있습니까? 내 코드의 어느 곳에도 나타나지 않습니다.

스크린 샷 1


10 가지 중 9 가지 경우 : 이것은 단지 원인 : yoru 스토리 보드의 일부보기 또는 항목의 경우 "설치됨"을 선택 취소합니다. (예를 들어, 개발 버튼이나 더 이상 필요하지 않은 것) 일반적으로 "설치되지 않은"을 잘못 처리합니다. 설치되지 않은 항목이 없으면 제약 조건이 남는 경우가 종종 있습니다. 종종 해결책은 잊어 버린 항목을 삭제하고 "설치되지 않은"항목 주위에있는 항목을 삭제하는 것입니다.
Fattie

답변:


442

게시물많은 도움 이 되었습니다 !

UIViewAlertForUnsatisfiableConstraints 기호 중단 점을 제안 된 조치로 추가 했습니다 .

Obj-C 프로젝트

po [[UIWindow keyWindow] _autolayoutTrace]

Objective-C 프로젝트에서 사용자 정의 조치가있는 기호 브레이크 포인트

스위프트 프로젝트

expr -l objc++ -O -- [[UIWindow keyWindow] _autolayoutTrace]

사용자 정의 동작이있는 상징적 인 중단 점

이 힌트를 통해 로그가 더 자세 해졌고 제약 조건이 손상된 뷰를 쉽게 식별 할 수있었습니다.

UIWindow:0x7f88a8e4a4a0
|   UILayoutContainerView:0x7f88a8f23b70
|   |   UINavigationTransitionView:0x7f88a8ca1970
|   |   |   UIViewControllerWrapperView:0x7f88a8f2aab0
|   |   |   |   UIView:0x7f88a8ca2880
|   |   |   |   |   *UIView:0x7f88a8ca2a10
|   |   |   |   |   |   *UIButton:0x7f88a8c98820'Archived'
|   |   |   |   |   |   |   UIButtonLabel:0x7f88a8cb0e30'Archived'
|   |   |   |   |   |   *UIButton:0x7f88a8ca22d0'Download'
|   |   |   |   |   |   |   UIButtonLabel:0x7f88a8cb04e0'Download'
|   |   |   |   |   |   *UIButton:0x7f88a8ca1580'Deleted'
|   |   |   |   |   |   |   UIButtonLabel:0x7f88a8caf100'Deleted'
|   |   |   |   |   *UIView:0x7f88a8ca33e0
|   |   |   |   |   *_UILayoutGuide:0x7f88a8ca35b0
|   |   |   |   |   *_UILayoutGuide:0x7f88a8ca4090
|   |   |   |   |   _UIPageViewControllerContentView:0x7f88a8f1a390
|   |   |   |   |   |   _UIQueuingScrollView:0x7f88aa031c00
|   |   |   |   |   |   |   UIView:0x7f88a8f38070
|   |   |   |   |   |   |   UIView:0x7f88a8f381e0
|   |   |   |   |   |   |   |   UIView:0x7f88a8f39fa0, MISSING HOST CONSTRAINTS
|   |   |   |   |   |   |   |   |   *UIButton:0x7f88a8cb9bf0'Retrieve data'- AMBIGUOUS LAYOUT for UIButton:0x7f88a8cb9bf0'Retrieve data'.minX{id: 170}, UIButton:0x7f88a8cb9bf0'Retrieve data'.minY{id: 171}
|   |   |   |   |   |   |   |   |   *UIImageView:0x7f88a8f3ad80- AMBIGUOUS LAYOUT for UIImageView:0x7f88a8f3ad80.minX{id: 172}, UIImageView:0x7f88a8f3ad80.minY{id: 173}
|   |   |   |   |   |   |   |   |   *App.RecordInfoView:0x7f88a8cbe530- AMBIGUOUS LAYOUT for App.RecordInfoView:0x7f88a8cbe530.minX{id: 174}, App.RecordInfoView:0x7f88a8cbe530.minY{id: 175}, App.RecordInfoView:0x7f88a8cbe530.Width{id: 176}, App.RecordInfoView:0x7f88a8cbe530.Height{id: 177}
|   |   |   |   |   |   |   |   |   |   +UIView:0x7f88a8cc1d30- AMBIGUOUS LAYOUT for UIView:0x7f88a8cc1d30.minX{id: 178}, UIView:0x7f88a8cc1d30.minY{id: 179}, UIView:0x7f88a8cc1d30.Width{id: 180}, UIView:0x7f88a8cc1d30.Height{id: 181}
|   |   |   |   |   |   |   |   |   |   |   *UIView:0x7f88a8cc1ec0- AMBIGUOUS LAYOUT for UIView:0x7f88a8cc1ec0.minX{id: 153}, UIView:0x7f88a8cc1ec0.minY{id: 151}, UIView:0x7f88a8cc1ec0.Width{id: 154}, UIView:0x7f88a8cc1ec0.Height{id: 165}
|   |   |   |   |   |   |   |   |   |   |   |   *UIView:0x7f88a8e68e10- AMBIGUOUS LAYOUT for UIView:0x7f88a8e68e10.minX{id: 155}, UIView:0x7f88a8e68e10.minY{id: 150}, UIView:0x7f88a8e68e10.Width{id: 156}
|   |   |   |   |   |   |   |   |   |   |   |   *UIImageView:0x7f88a8e65de0- AMBIGUOUS LAYOUT for UIImageView:0x7f88a8e65de0.minX{id: 159}, UIImageView:0x7f88a8e65de0.minY{id: 182}
|   |   |   |   |   |   |   |   |   |   |   |   *UILabel:0x7f88a8e69080'8-6-2015'- AMBIGUOUS LAYOUT for UILabel:0x7f88a8e69080'8-6-2015'.minX{id: 183}, UILabel:0x7f88a8e69080'8-6-2015'.minY{id: 184}, UILabel:0x7f88a8e69080'8-6-2015'.Width{id: 185}
|   |   |   |   |   |   |   |   |   |   |   |   *UILabel:0x7f88a8cc0690'16:34'- AMBIGUOUS LAYOUT for UILabel:0x7f88a8cc0690'16:34'.minX{id: 186}, UILabel:0x7f88a8cc0690'16:34'.minY{id: 187}, UILabel:0x7f88a8cc0690'16:34'.Width{id: 188}, UILabel:0x7f88a8cc0690'16:34'.Height{id: 189}
|   |   |   |   |   |   |   |   |   |   |   |   *UIView:0x7f88a8cc2050- AMBIGUOUS LAYOUT for UIView:0x7f88a8cc2050.minX{id: 161}, UIView:0x7f88a8cc2050.minY{id: 166}, UIView:0x7f88a8cc2050.Width{id: 163}
|   |   |   |   |   |   |   |   |   |   |   |   *UIImageView:0x7f88a8e69d90- AMBIGUOUS LAYOUT for UIImageView:0x7f88a8e69d90.minX{id: 190}, UIImageView:0x7f88a8e69d90.minY{id: 191}, UIImageView:0x7f88a8e69d90.Width{id: 192}, UIImageView:0x7f88a8e69d90.Height{id: 193}
|   |   |   |   |   |   |   |   |   |   |   *UIView:0x7f88a8f3cc00
|   |   |   |   |   |   |   |   |   |   |   |   *UIView:0x7f88a8e618d0
|   |   |   |   |   |   |   |   |   |   |   |   *UIImageView:0x7f88a8e5ba10
|   |   |   |   |   |   |   |   |   |   |   |   *UIView:0x7f88a8f3cd70
|   |   |   |   |   |   |   |   |   |   |   |   *UIImageView:0x7f88a8e58e10
|   |   |   |   |   |   |   |   |   |   |   |   *UIImageView:0x7f88a8e5e7a0
|   |   |   |   |   |   |   |   |   |   |   |   *UIView:0x7f88a8f3cee0
|   |   |   |   |   |   |   |   |   |   |   *UIView:0x7f88a8f3dc70
|   |   |   |   |   |   |   |   |   |   |   |   *UIView:0x7f88a8e64dd0
|   |   |   |   |   |   |   |   |   |   |   |   *UILabel:0x7f88a8e65290'Average flow rate'
|   |   |   |   |   |   |   |   |   |   |   |   *UILabel:0x7f88a8e712d0'177.0 ml/s'
|   |   |   |   |   |   |   |   |   |   |   |   *UILabel:0x7f88a8c97150'1299.4'
|   |   |   |   |   |   |   |   |   |   |   |   *UIView:0x7f88a8f3dde0
|   |   |   |   |   |   |   |   |   |   |   |   *UILabel:0x7f88a8f3df50'Maximum flow rate'
|   |   |   |   |   |   |   |   |   |   |   |   *UILabel:0x7f88a8cbfdb0'371.6 ml/s'
|   |   |   |   |   |   |   |   |   |   |   |   *UILabel:0x7f88a8cc0230'873.5'
|   |   |   |   |   |   |   |   |   |   |   |   *UIView:0x7f88a8f3e2a0
|   |   |   |   |   |   |   |   |   |   |   |   *UILabel:0x7f88a8f3e410'Total volume'
|   |   |   |   |   |   |   |   |   |   |   |   *UILabel:0x7f88a8cc0f20'371.6 ml'
|   |   |   |   |   |   |   |   |   |   |   |   *UIView:0x7f88a8f3e870
|   |   |   |   |   |   |   |   |   |   |   |   *UILabel:0x7f88a8f3ea00'Time do max. flow'
|   |   |   |   |   |   |   |   |   |   |   |   *UILabel:0x7f88a8cc0ac0'3.6 s'
|   |   |   |   |   |   |   |   |   |   |   |   *UIView:0x7f88a8f3ee10
|   |   |   |   |   |   |   |   |   |   |   |   *UILabel:0x7f88a8f3efa0'Flow time'
|   |   |   |   |   |   |   |   |   |   |   |   *UILabel:0x7f88a8cbf980'2.1 s'
|   |   |   |   |   |   |   |   |   |   |   |   *UIView:0x7f88a8f3f3e0
|   |   |   |   |   |   |   |   |   |   |   |   *UILabel:0x7f88a8f3f570'Voiding time'
|   |   |   |   |   |   |   |   |   |   |   |   *UILabel:0x7f88a8cc17e0'3.5 s'
|   |   |   |   |   |   |   |   |   |   |   |   *UIView:0x7f88a8f3f9a0
|   |   |   |   |   |   |   |   |   |   |   |   *UILabel:0x7f88a8f3fb30'Voiding delay'
|   |   |   |   |   |   |   |   |   |   |   |   *UILabel:0x7f88a8cc1380'1.0 s'
|   |   |   |   |   |   |   |   |   |   |   |   *UIView:0x7f88a8e65000
|   |   |   |   |   |   |   |   |   |   |   |   *UIButton:0x7f88a8e52f20'Show'
|   |   |   |   |   |   |   |   |   |   |   |   *UIImageView:0x7f88a8e6e1d0
|   |   |   |   |   |   |   |   |   |   |   |   *UIButton:0x7f88a8e52c90'Send'
|   |   |   |   |   |   |   |   |   |   |   |   *UIImageView:0x7f88a8e61bb0
|   |   |   |   |   |   |   |   |   |   |   |   *UIButton:0x7f88a8e528e0'Delete'
|   |   |   |   |   |   |   |   |   |   |   |   *UIImageView:0x7f88a8e6b3f0
|   |   |   |   |   |   |   |   |   |   |   |   *UIView:0x7f88a8f3ff60
|   |   |   |   |   |   |   |   |   *UIActivityIndicatorView:0x7f88a8cba080
|   |   |   |   |   |   |   |   |   |   UIImageView:0x7f88a8cba700
|   |   |   |   |   |   |   |   |   *_UILayoutGuide:0x7f88a8cc3150
|   |   |   |   |   |   |   |   |   *_UILayoutGuide:0x7f88a8cc3b10
|   |   |   |   |   |   |   UIView:0x7f88a8f339c0
|   |   UINavigationBar:0x7f88a8c96810
|   |   |   _UINavigationBarBackground:0x7f88a8e45c00
|   |   |   |   UIImageView:0x7f88a8e46410
|   |   |   UINavigationItemView:0x7f88a8c97520'App'
|   |   |   |   UILabel:0x7f88a8c97cc0'App'
|   |   |   UINavigationButton:0x7f88a8e3e850
|   |   |   |   UIImageView:0x7f88a8e445b0
|   |   |   _UINavigationBarBackIndicatorView:0x7f88a8f2b530

Legend:
    * - is laid out with auto layout
    + - is laid out manually, but is represented in the layout engine because translatesAutoresizingMaskIntoConstraints = YES
     - layout engine host

그런 다음 실행을 일시 중지 중지 하고 문제가있는보기의 배경색을 명령으로 변경했습니다 ( 물론 객체0x7f88a8cc2050메모리 주소로 대체 ) ...

오브제 C

expr ((UIView *)0x7f88a8cc2050).backgroundColor = [UIColor redColor]

스위프트 3.0

expr -l Swift -- import UIKit
expr -l Swift -- unsafeBitCast(0x7f88a8cc2050, to: UIView.self).backgroundColor = UIColor.red

... 그리고 결과 대단했습니다!

힌트보기

놀랍습니다! 희망이 있습니다.


3
@iAnurag 실행이 일시 중지되면 콘솔 영역에서 명령을 실행할 수 있습니다.
Thomás Calmon

2
@TomCalmon 나는 똑같이 ...하지만 그것은 다음과 같은 오류를 보여줍니다 rror: Execution was interrupted, reason: EXC_BAD_ACCESS (code=1, address=0x7f88a8cc2050). The process has been returned to the state before expression evaluation.
iAnurag

2
expr -l objc++ -O -- [[UIWindow keyWindow] _autolayoutTrace]nil나를 위해 돌아온다
Igor Andreev 12

2
0x7f88a8cc2050을 객체의 메모리 주소로 바꾸고 실행이 일시 중지 될 때 콘솔에서 명령을 실행하십시오.
Tom Howard

3
놀랍습니다. 여기서 유용한 팁은 문제를 바로 잡는 데 완전히 도움이되었습니다. 항목이 빨간색으로 변경되면 가능하면 실행을 계속하면 하이라이트가 표시됩니다.
Aaron

255

을 추가하고 싶을 것 Symbolic Breakpoint입니다. Apple 은이를 수행하는 방법에 대한 훌륭한 안내서 를 제공합니다 .

  1. 중단 점 네비게이터여 cmd+7( cmd+8엑스 코드 9)를
  2. Add왼쪽 하단 의 버튼을 클릭하십시오
  3. 고르다 Add Symbolic Breakpoint...
  4. Symbol그냥 입력 이라고 말하는 곳UIViewAlertForUnsatisfiableConstraints

또한 다른 중단 점처럼 처리하거나 설정, 해제 또는 조치를 추가하거나 메시지를 로그 할 수 있습니다.


55
이 힌트로 문제를 더 잘 디버깅하는 방법을 이해하지 못합니다. 상징적 인 중단 점을 추가했지만 여전히 문제에 대한 충분한 정보를 제공하지 않습니다. 유일한 방법은 한 줄씩 읽고 문제의 원인을 이해하는 것입니다. 그렇지 않으면 제약 조건을 지우고 미리보기를 미리보기와 함께 추가하는 것이 가장 도움이됩니다!
Alex Cio

11
중단 점에서 정지 한 후 자세한 정보를 얻는 데 도움이 될 수 있습니다. staxmanade.com/2015/06/debugging-ios-autolayout-issues
fabb

1
IB에서 직접 제약 조건에 식별자를 부여 할 수 있다는 것을 추가하면 디버깅 할 때 볼 수있는 이름입니다.
Mark A. Donohoe

2
(@MarqueIV의 후속 조치) NSLayoutConstraintidentifieriOS 7 - Xcode 7 이상 부터 속성 을 가졌으며, IB 스토리 보드와 코드에서 모두 설정할 수 있습니다. 식별자를 설정하여 사용자가 쉽게 디버그 로그에 시스템 생성 및 사용자 생성 제약 구별 할 수, 예를 들어 myConstraint.identifier = "centered image"(소스 및 예 : useyourloaf.com/blog/using-identifiers-to-debug-autolayout )
PDK

@AlexCio 어떻게 도움이 되나요? 가장 적은 일이 발생하는 순간 일시 중지됩니다. 역 추적하고 원점을 찾을 수있는 스택 추적을 제공합니다.
Honey

10

Stephen의 조언을 따르고 코드와 whoa를 디버깅하려고했습니다! 효과가있었습니다. 대답은 디버그 메시지 자체에 있습니다.

Will attempt to recover by breaking constraint NSLayoutConstraint:0x191f0920 H:[MPKnockoutButton:0x17a876b0]-(34)-[MPDetailSlider:0x17a8bc50](LTR)>

위의 줄은이 제약 조건을 제거하여 런타임이 작동했음을 나타냅니다. 버튼에 수평 간격이 필요하지 않을 수도 있습니다 (MPKnockoutButton). 이 제약 조건을 지우면 런타임에 불평하지 않으며 원하는 동작을 얻습니다.


3
컴파일러? 런타임을 의미합니까? 컴파일러가 제약 조건을 제거하지 않았습니다. 컴파일러는 런타임에서 처리 할 수 ​​있도록 런타임 상태를 유지하므로 런타임 중에 "제약 조건을 해제하여 복구" 합니다 .
drhr

그래, 난 런타임 의미
Sategroup

2

시스템이 깨뜨려야 할 제약 조건을 제거하려고 할 때마다 제약 조건이 더 이상 IB를 충족시키기에 충분하지 않습니다 (즉, IB의 "결석 제약 조건"표시). 불완전하고 사용되지 않음을 의미합니다. 실제로 우선 순위를 낮게 설정하려는 제약 조건을 설정 하여이 문제를 해결했습니다.이 제한은 시스템이 제약 조건을 정상적으로 중단 할 수있게합니다. 아마도 최상의 솔루션은 아니지만 내 문제를 해결하고 결과 제약 조건이 완벽하게 작동했습니다.


2
일반적으로 런타임시 제거되는 자리 표시 자 제약 조건을 사용하려는 상황입니다. 제약 조건을 자리 표시 자 제약 조건으로 만들려면 제약 조건 관리자로 이동하여 "빌드 타임에 제거"를 클릭하십시오. 이를 나타 내기 위해 IB 도면 영역의 구속 조건 I- 빔 기호가 파란색에서 회색으로 어떻게 변하는 지 확인하십시오.
spencery2

1
나는 같은 문제가 있었다. 깨진 구속 조건을 제거하면 디자인이 깨졌습니다. 그래서 우선 순위를 중간으로 설정했습니다.
Jeremy Piednoel
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.