2009-05-23 54 views
7

我在Cocoa Bindings中一直遇到的一件事是錯誤呈現,例如,當用戶在格式化程序附加的文本字段中輸入錯誤的值時。通常我會在響應鏈中的某處覆蓋willPresentError:,但是我的問題是由Bindings系統創建的NSError對象沒有足夠的信息來告訴我什麼失敗了,或者它是否是我對定製感興趣的錯誤。我可以完全從等式中刪除綁定,並在驗證問題發生時創建自己的錯誤,但我覺得我會以這種方式拋出一些有用的東西。如何在綁定涉及時重寫NSError表示?

我已經能夠通過實現NSControl委託方法並將失敗的控件存儲在我的視圖控制器中的實例變量中解決此問題。如果在willPresentError:時間週期內它不是零,那麼我知道什麼不能驗證。

- (BOOL)control:(NSControl *)control didFailToFormatString:(NSString *)string errorDescription:(NSString *)error; 
{ 
    _errorSender = [control retain]; 
    return NO; 
} 

- (NSError *)willPresentError:(NSError *)error; 
{ 
    if (_errorSender != nil) 
    { 
     NSMutableDictionary *userInfo = [NSMutableDictionary dictionaryWithDictionary:[error userInfo]]; 
     NSString *help = NSLocalizedString(@"Why are you always messing up? You are a terrible person.", @""); 

     [_errorSender release]; 
     _errorSender = nil; 
     [userInfo setObject:help forKey:NSLocalizedRecoverySuggestionErrorKey]; 

     return [NSError errorWithDomain:[error domain] code:[error code] userInfo:userInfo]; 
    } 

    return [super willPresentError:error]; 
} 

這工作時,第一個響應的變化,而不是當我打電話commitEditing視圖控制器,所以它只是部分地對我很有用。

我能看到的唯一的其他選擇是將NSFormatter排除在外,並在我的Core Data託管對象中使用validateValue:forKey:error:來處理驗證。這對使用格式化程序沒有太大意義,但至少我可以完全控制NSError對象。

我覺得我必須錯過某些東西,因爲這種斷開與錯誤處理有關。有什麼建議麼?

回答

4

I could completely remove bindings from the equation and create my own errors when validation problems occur, but I feel like I would be throwing out some useful stuff that way.

您可以使用NSUnderlyingErrorKey另一個錯誤來包裝一個錯誤(該密鑰的對象)(其userInfo一個包含密鑰)。

The only other option I can see is taking NSFormatter out of the equation, and using validateValue:forKey:error: in my Core Data managed objects to handle validation. This doesn't make as much sense to me as using a formatter, but at least I'd have full control over the NSError object.

這些是兩個不同的級別,它們不是相互排斥的。格式化程序驗證位於視圖圖層;鍵值驗證(在這種情況下,在您的託管對象中)位於模型層。

如果有問題的驗證應該發生在視圖層,那麼子類NSFormatter類(如果還沒有的話)並且實現getObjectValue:forString:errorDescription:以返回更具體的錯誤描述。 (我不知道綁定是否實際使用此錯誤的描述,但是,你應該檢查。)

如果驗證應在模型層發生,實現validate<Key>:error:(的validateValue:forKey:error:單屬性的版本)在您的NSManagedObject子類。

如果某些約束位於模型層,而其他約束位於視圖層,則同時執行這兩個操作。如果這對您的應用程序和支票有意義,您可以自由地在格式化程序和模型中的其他檢查中執行一些檢查。

+1

我是NSFormatter的子類,雖然綁定確實使用了NSString錯誤消息,但我提供的最終NSAlert仍然是相當裸露的骨骼(我想爲錯誤添加一個恢復建議,至少)。我正在做的驗證似乎更適合我的NSFormatter子類,這就是爲什麼我對我的模型實現鍵值驗證猶豫不決。我最終會做各種與數據模型無關的字符串解析,只是爲了能夠在出現問題時自定義前端錯誤消息。 – 2009-05-23 20:09:37