2013-05-02 1 views
7

XCode가 불만족스러운 NSLayoutConstraints을 잡아 내고 이에 대한 정보를 제공하지만 컨트롤/제약 조건의 메모리 주소를 취하는 방법을 알지 못해서 문제가있는 실제 컨트롤.UI 컨트롤에 만족스럽지 않은 NSLayoutConstraints의 메모리 주소를 매핑하는 중

내 응용 프로그램은 상당히 큽니다 (약 20 개의 화면), 일부는 큰 UIViewController이며 여러 개의 하위보기 컨트롤러가 있습니다. 일부는 사용자 정의 셀이있는 UITableView와 사용자 정의 셀이있는 UICollectionView입니다. 당신이 볼 수 있듯이

2013-05-02 11:18:53.225 Smile[7519:c07] Unable to simultaneously satisfy constraints. 
    Probably at least one of the constraints in the following list is one you don't want. Try this: (1) look at each constraint and try to figure out which you don't expect; (2) find the code that added the unwanted constraint or constraints and fix it. (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints) 
(
    "<NSAutoresizingMaskLayoutConstraint:0x16083b60 h=-&- v=-&- UIView:0xa5a1d00.width == UIWindow:0xa09eee0.width>", 
    "<NSLayoutConstraint:0xa5a2180 V:[UIView:0xa59f160]-(954)-| (Names: '|':UIView:0xa5a1d00)>", 
    "<NSLayoutConstraint:0xa5a2140 V:|-(0)-[UIView:0xa59f160] (Names: '|':UIView:0xa5a1d00)>", 
    "<NSAutoresizingMaskLayoutConstraint:0xa593340 h=--- v=--- H:[UIWindow:0xa09eee0(768)]>" 
) 

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0xa5a2180 V:[UIView:0xa59f160]-(954)-| (Names: '|':UIView:0xa5a1d00)> 

Break on objc_exception_throw to catch this in the debugger. 
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful. 

, 메모리가 있습니다 : 내 콘솔에서 정보를 (가로 회전에서 발생)이 오류의 원인 여기

을 시침 시간의 지옥을 갖는거야 주소가 나열되어 있습니다. 조사 창에있는 검색 창에 이들을 붙여 넣어도 그다지 알려주지 않습니다. 또한 스레드와 대기열 호출 스택을 샅샅이 뒤져서,이 중단 점 (예외 중단 점)에 대해서만 디스 어셈블 된 코드를 얻습니다.

답변

0

here과 같이 visualizeConstraints:을 사용해 볼 수 있으며 잘못된 제약 조건을 찾을 수 있는지 확인하십시오.

+0

visualizeConstraints는 OS X에서만 작동합니다. –

+0

웁스! 어떤 이유로 UILayoutConstraint가 문제라고 생각했기 때문에 이것이 Mac에 있다고 생각했습니다. 나는 충분히 신중하게 질문을 읽지 않았다고 생각한다. –

4

짧은 대답은 실제로는 아닙니다. OS X에는보기를 식별하는 데 NSLayoutConstraint에서 사용하는보기에 설정할 수있는 식별자 속성이 있지만 아직 iOS에는 존재하지 않습니다.

그러나 iOS에서 비슷한 것을 구현하는 '해결 방법'이 있지만 꽤 좋지는 않습니다. 먼저 UIView 카테고리에서 각 뷰의 이름을 지정해야합니다. 그런 다음 NSLayoutConstraint 설명에 대한 출력을 업데이트하여 새 태그를 사용해야합니다. 당신이 그들을 그렇게

self.view.nametag = @"MyUsefulName"; 

처럼 뷰 이름을 설정하거나 정의 할 수있을 것입니다 그리고

#import <objc/objc-runtime.h> 

static const char nametag_key; 
@implementation NSLayoutConstraint (Nametags) 

- (NSString *)description { 
    NSMutableString *myDescription = [NSMutableString stringWithFormat:@"%@, ", [self asciiArtDescription]]; 
    UIView *firstView = (UIView *)[self firstItem]; 
    if (firstView) { 
     [myDescription appendFormat:@"First View: 0x%0x: %@, ", (int)firstView, firstView.nametag]; 
    } 

    UIView *secondView = (UIView *)[self secondItem]; 
    if (secondView) { 
     [myDescription appendFormat:@"Second View: 0x%0x: %@", (int)secondView, secondView.nametag]; 
    } 

    return myDescription; 
} 
@end 

@implementation UIView (Nametags) 
- (id) nametag { 
    return objc_getAssociatedObject(self, (void *) &nametag_key); 
} 

- (void)setNametag:(NSString *) theNametag { 
    objc_setAssociatedObject(self, (void *) &nametag_key, theNametag, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 
} 
@end 

NSLayout

의 출력을 변경하기 위해, 다음과 같이

@interface NSLayoutConstraint (Nametags) 
- (NSString *)asciiArtDescription; 
@end 

@interface UIView (Nametags) 
@property (nonatomic, strong) NSString *nametag; 
@end 

그런 다음 구현을 제공 IB

nametag in IB

마지막으로 제약 조건을 덤프 할 때 출력에서 ​​제공 한 이름을 얻을 수 있습니다. 디버그 빌드에서 민간 [NSLayoutConstraint의 asciiArtDescription] 방법을 액세스하기 때문에

"V:|-(202)-[UIView:0x75606f0], First View: 0x75606f0: Blue View, Second View: 0x7560bd0: (null)", 
"V:[UIView:0x75606f0]-(72)-|, First View: 0x7560bd0: (null), Second View: 0x75606f0: Blue View", 
"V:[UIView:0x7560bd0(548)], First View: 0x7560bd0: (null), " 

당신은 응용 프로그램에서 그것을 제공되지 않습니다,이 코드를 사용해야합니다.

+0

흥미로운 기술. 이것은 처음부터 알고 있고 그것을 당신의 표준 구현 루틴의 일부로 만들면 정말 유용 할 수 있습니다. 몇 가지 컨트롤이 의심 스럽기 때문에이 기술을 적용하고 어떤 일이 발생하는지 살펴 보겠습니다. – VaporwareWolf

+0

이것은 흥미로운 접근 방법입니다. 유용한 추가 기능은 새 속성 하나를 만드는 대신 UIView에 기존의'accessibilityLabel' 속성을 사용하는 것입니다. 아무튼'accessibilityLabel' 속성을 채워야합니다. :) –

+0

이 방법은 http://www.objc.io/issue-3/advanced-auto-layout-toolbox.html의 디버그 섹션 – giampaolo

6

다음 웹 사이트 덕분에 해결책을 찾았습니다 : Debugging iOS AutoLayout IssuesDancing with the Debugger. Xcode 콘솔 덕분에 문제가 발생한보기를 확인할 수 있습니다.

솔루션 :

  • 1 단계 :

    • 를 열고 중단 점 네비게이터 (cmd를 + 7)
    • (가) 왼쪽 하단
    • 선택 '에서'추가 '버튼을 클릭 기호식 중단 점 추가 '
    • 여기서'기호 '유형은 UIViewAlertForUnsatisfiableConstraints
    • 입니다.
  • 2 단계 : 프로젝트를 실행하십시오. 콘솔에서 Will attempt to recover by breaking constraint <NSLayoutConstraint:0x7fc82d3e18a0 H:[UIView:0x7fc82aba1210(768)]>을 인쇄하면보기의 메모리 주소 (여기에서 0x7fc82aba1210)를 복사하십시오.

  • 3 단계 :이 콘솔에서이 명령을 사용하여 어느 하나의 알이보기의 배경을 변경 : e (void)[0x7fc82d3e18a0 setBackgroundColor:[UIColor redColor]]

  • 4 단계 : 프로그램을 계속 업데이트 된 UI를 참조하십시오. 빨간색 배경색의보기가 문제의보기입니다.

  • 5 단계 : IB로 돌아가서이보기에서 문제가되는 제약 조건을 찾으십시오.

+1

에서 설명합니다. 3 단계가 훌륭했습니다! –

관련 문제