我不完全確定你要在那裏做什麼 - 你的回調是一個塊......是故意的嗎?我希望你的方法是這個樣子:
- (void)signInAccountWithUserName:(NSString *)userName password:(NSString *)password;
如果回調的目的是執行上完成一些額外的代碼(當你調用該方法規定),那麼塊將是有益的。例如,你的方法是這樣的:
- (void)signInAccountWithUserName:(NSString *)userName
password:(NSString *)password
completion:(void (^)(void))completionBlock
{
// ...
// Log into the account with `userName` and `password`...
//
if (successful) {
completionBlock();
}
}
然後調用像這樣的方法:
[self signInAccountWithUserName:@"Bob"
password:@"BobsPassword"
completion:^{
[self displayBalance]; // For example...
}];
調用這個方法將盡快使用戶登錄到該帳戶,然後爲完成,顯示餘額。這顯然是一個人爲的例子,但希望你明白。
如果這不是您想要的東西,那麼只需使用上面的方法簽名即可。
EDIT(使用successful
變量A更好的例子):
更好的設計。將傳遞一個布爾回描述登錄如何去完成塊:
- (void)signInAccountWithUserName:(NSString *)userName
password:(NSString *)password
completion:(void (^)(BOOL success))completionBlock
{
// Log into the account with `userName` and `password`...
// BOOL loginSuccessful = [LoginManager contrivedLoginMethod];
// Notice that we are passing a BOOL back to the completion block.
if (completionBlock != nil) completionBlock(loginSuccessful);
}
您還會看到,這次我們在調用它之前檢查參數completionBlock
不是nil
- 如果您想允許這種方法od使用而不使用完成塊。您可以使用此方法,像這樣:
[self signInAccountWithUserName:@"Bob"
password:@"BobsPassword"
completion:^(BOOL success) {
if (success) {
[self displayBalance];
} else {
// Could not log in. Display alert to user.
}
}];
更妙的是(!如果你能原諒的例子大片),如果它會是有益的用戶知道失敗的原因,返回NSError
對象:
- (void)signInAccountWithUserName:(NSString *)userName
password:(NSString *)password
completion:(void (^)(NSError *error))completionBlock
{
// Attempt to log into the account with `userName` and `password`...
if (loginSuccessful) {
// Login went ok. Call the completion block with no error object.
if (completionBlock != nil) completionBlock(nil);
} else {
// Create an error object. (N.B. `userInfo` can contain lots of handy
// things! Check out the NSError Class Reference for details...)
NSInteger errorCode;
if (passwordIncorrect) {
errorCode = kPasswordIncorrectErrorCode;
} else {
errorCode = kUnknownErrorCode;
}
NSError *error = [NSError errorWithDomain:MyLoginErrorDomain code:errorCode userInfo:nil];
if (completionBlock != nil) completionBlock(error);
}
}
呼叫者就可以使在完成塊的使用NSError
來決定如何進行(最有可能的,描述到什麼地方出了錯用戶)。這種模式稍微不常見(儘管完全有效);大多NSError
S被間接指針在NSFileWrapper
小號-initWithURL:options:error:
方法返回,例如:
NSError *error;
NSFileWrapper *fw = [[NSFileWrapper alloc] initWithURL:url options:0 error:&error];
// After the above method has been called, `error` is either `nil` (if all went well),
// or non-`nil` (if something went wrong).
在登錄例子,但是,我們可能期待的登錄嘗試採取一定量的時間來完成(例如登錄到一個在線帳戶),所以使用完成處理程序來傳回錯誤是完全合理的。
謝謝你,這幫了我。是的,這是故意的。 – Jesse
我可能會設計它2塊:成功和失敗 – vikingosegundo
@vikingosegundo:是的,很好的建議。儘管根據上下文,將該成功作爲「BOOL」返回可能更容易,或者可能通過指針間接傳遞「NSError」對象以確定登錄進行得如何。 – Stuart