2012-09-08 36 views
0

我有一個NSPopover內的自定義視圖。它應該根據用戶輸入進行更改,並且在用戶第一次與其交互時進行更改,但無法重繪以下時間。NSView只在斷點重繪

我試圖把NSLog放在-drawRect:方法中,並且在正常執行過程中它不會被調用。當我嘗試調試並在方法內部放置一個斷點時,它會正常調用,並且應用程序按其應有的方式工作。

我每次需要重繪時都明確地調用視圖-setNeedsDisplay:方法。 我不明白爲什麼它應該有所作爲。

下面是更新視圖狀態的代碼。這些方法是NSTextField委託方法-textDidChange:的一部分,我檢查了每次用戶在與彈出窗口相關聯的文本字段中輸入內容時都會調用這些方法。

[tokenCloud tokensToHighlight:[NSArray arrayWithObject:completeSuggestionString]]; 
tokenCloud.tokens = filteredTokens; 
[tokenCloud setNeedsDisplay:YES]; 

該意見是一系列隱藏按鈕。第一行更新彈出窗口中的所有按鈕以及第二個添加或刪除按鈕的狀態。他們都正常工作,因爲他們第一次被稱爲視圖正確更新。我還檢查了tokenCloud中按鈕的狀態及其屬性tokens的狀態是否正確更新。問題是NSView子類tokenCloud不會重繪,因此更改不會在第二次在UI中反映出來。

這裏是視圖的繪製方法:

- (void)drawRect:(NSRect)rect { 
    [self recalculateButtonLocations]; 
    NSLog(@"Redrawn"); 
} 

再次調用此方法通常每次如果我把一個斷點在[self recalculateButtonLocations];我更新視圖。如果我讓應用程序正常運行,則第二次更新視圖時,控制檯中沒有任何記錄。如果我在recalculateButtonLocations方法中包含NSLog,同樣的事情,第二次沒有任何記錄意味着該方法未被調用。

+1

bbum您可以添加表現出的問題最少的代碼例子嗎? – pqnet

+0

我的歉意。我編輯了帖子並添加了代碼。 – Jacopo

+0

由於它是一個自定義視圖,因此在調用'super'之前嘗試覆蓋'setNeedsDisplay'以包含日誌。 – pqnet

回答

0

編輯2:對於未來的讀者,抱歉,這個答案質量差。其中大部分是無用的,有用的部分應該作爲評論。我會刪除它,但我覺得這是不真誠的。希望有這個問題的人可以在鏈接的答案中找到更多的見解,這些答案包含一些信息,說明爲什麼有時候添加斷點可能會改變程序的流程。

取決於你如何繪製的按鈕,它可能是一個更好的主意,用layoutSubviewssetNeedsLayout,比drawRect重新定位子視圖。 [編輯:沒有看到這是Mac OS,而不是iOS。 layout的確是相當於layoutSubviews並且對於NSView,其中子視圖安排應做一個setNeedsLayout]

沒有更多的信息不能給出任何更多的建議。然而,它與斷點一起工作的事實是好奇的。我無法看到爲什麼在方法調用行上有斷點會導致它更頻繁地調用;該方法應該被調用與否,不管是否有斷點,看起來這個錯誤不能單獨用上面的代碼複製......讓我覺得這是代碼中的其他內容導致這個問題。


一些類似的問題與你的斷點改變代碼流。也許睡覺的代碼/添加一個停頓,而不是斷點,看看它是否工作?如果是這樣,它可能表明下面的問題之一。

導致斷點改變代碼工作原理的第一個原因是 競爭條件。它基本上是這樣的:

Without breakpoints: 
    make some asynchronous request 
    do something with response 
    ERROR because request hasn't responded yet 

With breakpoints: 
    send some asynchronous request 
    wait for user to continue 
    response arrived while waiting for the continue 
    do something with response 
    OK! 

^Niet的黑暗ABSOL從Breakpoint changes program flow

我以前見過這個,我的猜測是,該事件越來越 貼得太快了系統來處理(因爲它真的只有 每秒處理不超過20個關鍵事件)。我猜想, 放入類似usleep(100000)(暫停線程爲1/10的 秒)將有相當大的幫助。

^戴夫德朗從CGKeyEvent Pasting working with Breakpoints, but not without

通常表示爭用條件;你的代碼依賴於線程 在線程B命中某些特定狀態之前完成或不完成某些事情。

^從EXC_BAD_ACCESS, but not when using breakpoints

+0

我似乎無法在'NSView'中找到'layoutSubviews'方法。你的意思是''佈局'。這個問題是它似乎適用於基於約束的視圖,這不是我的情況。無論如何,我總是可以試着用約束來實現它。感謝您的建議,但不幸的是contentMode不可用於可可中的'NSViews'。 – Jacopo

+0

啊,對不起。我沒有看到iOS或Mac OS的標籤,並且認爲您正在開發使用UI類系列的iOS應用程序(UIView具有contentMode和layoutSubviews)。對於那個很抱歉! xD – Metabble

+0

沒問題。無論如何感謝您花時間提出建議。 – Jacopo