2013-05-02 83 views
7

我明白,XCode將捕獲不可批准的NSLayoutConstraints並給你一些關於它的信息,但我不知道如何獲取控件/約束的內存地址並將其映射到有問題的實際控制。將令人難以置信的NSLayoutConstraints的內存地址映射到UI控件

我的應用程序是相當大(約20屏),有些是大UIViewControllers與內他們幾個子視圖控制器。一些是帶有自定義單元的UITableViews和帶有自定義單元的UICollectionViews。我在的時候套結下來這個錯誤的原因(這發生在橫向旋轉)

這裏地獄從我的控制檯的信息:

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

您可以嘗試使用visualizeConstraints:,如here所述,然後查看是否可以通過這種方式找到錯誤的約束。

+0

visualizeConstraints只適用於OS X – 2013-05-02 19:34:35

+0

哎呀!出於某種原因,我認爲UILayoutConstraint是一件事情,因此我認爲這是在Mac上。我想我沒有仔細閱讀這個問題! – 2013-05-02 19:50:30

4

簡短的答案是不是真的,OS X具有可對所使用的NSLayoutConstraint,以幫助確定的意見,但並不在iOS上還存在一個視圖設置標識屬性。

但是有一個「工作圍繞」落實在iOS類似的東西,但它是不漂亮。首先,您必須爲每個視圖建立一個名稱,這在UIView類別中完成。然後你必須更新NSLayoutConstraint描述的輸出來使用新的標籤。

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

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

然後提供執行如下命令來改變NSLayout

#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 

隨後的輸出,你就可以在你的意見設置的名字,像這樣

self.view.nametag = @"MyUsefulName"; 

,或把它們IB

nametag in IB

最後,當曾經爲你傾倒約束你會得到你的輸出提供的名稱。

"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), " 

在你的調試版本時,才應使用此代碼,不出貨它的應用程序,因爲它訪問私人[NSLayoutConstraint asciiArtDescription]方法。

+0

有趣的技術。如果您從一開始就瞭解它並將其作爲您的標準實施例程的一部分,這可能非常有用。我懷疑有一些控件,所以我會應用這個技術,看看會發生什麼。 – VaporwareWolf 2013-05-02 21:52:44

+0

這確實是一個有趣的方法。有用的補充是隻使用'UIView'上現有的accessibilityLabel屬性,而不是創建一個新的屬性。無論如何,你應該填寫'accessibilityLabel'屬性。 :) – 2013-11-07 02:57:52

+0

此方法也在http://www.objc.io/issue-3/advanced-auto-layout-toolbox.html中解釋,在調試部分 – giampaolo 2014-02-28 16:46:02

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非常棒! – 2015-07-06 11:43:26

相關問題