在 iPhone 应用程序中等待异步方法完成如何更好?
大家。 我想了解,当异步方法具有“didFinish:@selector(SEL)”参数时,我应该如何处理情况。 我的代码示例是:
//
// Authentication check
- ( void )authenticationSuccess: ( GDataServiceTicket* ) ticket
authenticatedWithError: ( NSError* ) error {
if ( error == nil )
{
NSLog( @"authentication success" );
}
else
{
NSLog( @"authentication error" );
}
}
//
- ( void ) fetchFeedOfSpreadsheets {
//create and authenticate to a google spreadsheet service
if ( !(mService) )
{
GDataServiceGoogleSpreadsheet *service = [self spreadsheetService];
[mService autorelease];
mService = [service retain];
}
// check autentication success ( invoke "authenticationSuccess" method for debug success & error )
[mService authenticateWithDelegate: self
didAuthenticateSelector:@selector(authenticationSuccess:
authenticatedWithError:) ];
// HERE I WANT TO MAKE A PAUSE AND WHAIT THE RESULT, EITHER I AUTHENTICATED OR NOT
// AND MAKE AN "IF" STATEMENT TO CONTINTUE WORKING ON SERVER, OR RETURN ERROR
//fetch retrieves the feed of spreadsheets entries
NSURL *feedURL = [ NSURL URLWithString: kGDataGoogleSpreadsheetsPrivateFullFeed ];
GDataServiceTicket *ticket;
ticket = [mService fetchFeedWithURL: feedURL
delegate: self
didFinishSelector: @selector(spreadsheetsTicket:finishedWithFeed:
error: ) ];
// HERE I WANT TO WAIT SECOND TIME. I WANT "spreadsheetsTicket:
// finishedWithFeed:error:" TO PROCCEED ERROR AND PUT A FEED IN SOME NSARRAY OBJECT
// AND AFTER THAT I WANT TO WORK WITH THAT NSARRAY RIGHT HERE
}
我很清楚,我可以将我想要的代码推入“authenticationSuccess”方法部分的末尾,但也很清楚,这是解决问题的错误方法。有很多这样的情况,我使用选择器参数调用异步方法,并且我想找到一个为我提供灵活的代码编写的解决方案。
提前致谢。
everybody.
I want to understand, how i shoud procceed situations when an asynchronous method has "didFinish:@selector(SEL)" parameter.
My code example is:
//
// Authentication check
- ( void )authenticationSuccess: ( GDataServiceTicket* ) ticket
authenticatedWithError: ( NSError* ) error {
if ( error == nil )
{
NSLog( @"authentication success" );
}
else
{
NSLog( @"authentication error" );
}
}
//
- ( void ) fetchFeedOfSpreadsheets {
//create and authenticate to a google spreadsheet service
if ( !(mService) )
{
GDataServiceGoogleSpreadsheet *service = [self spreadsheetService];
[mService autorelease];
mService = [service retain];
}
// check autentication success ( invoke "authenticationSuccess" method for debug success & error )
[mService authenticateWithDelegate: self
didAuthenticateSelector:@selector(authenticationSuccess:
authenticatedWithError:) ];
// HERE I WANT TO MAKE A PAUSE AND WHAIT THE RESULT, EITHER I AUTHENTICATED OR NOT
// AND MAKE AN "IF" STATEMENT TO CONTINTUE WORKING ON SERVER, OR RETURN ERROR
//fetch retrieves the feed of spreadsheets entries
NSURL *feedURL = [ NSURL URLWithString: kGDataGoogleSpreadsheetsPrivateFullFeed ];
GDataServiceTicket *ticket;
ticket = [mService fetchFeedWithURL: feedURL
delegate: self
didFinishSelector: @selector(spreadsheetsTicket:finishedWithFeed:
error: ) ];
// HERE I WANT TO WAIT SECOND TIME. I WANT "spreadsheetsTicket:
// finishedWithFeed:error:" TO PROCCEED ERROR AND PUT A FEED IN SOME NSARRAY OBJECT
// AND AFTER THAT I WANT TO WORK WITH THAT NSARRAY RIGHT HERE
}
I's clear, that i can push the code i want into the end of "authenticationSuccess" method section, but it's also clear, that it's a wrong a way to solve the proble. There a number of situations like this, where i call an asynchronous method with a selector parameter, and i want to find a solution providing me a flexible code writing.
Thanks in advance.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
Objective-C 中的标准做法是将身份验证后执行的代码放在
authenticationSucess:
方法中。你可能不喜欢这样,但这就是生活。很多人和你有同样的抱怨,所以
在 iOS 4 及更高版本上,有一种称为“块”的东西,允许您在启动身份验证的方法中编写要在身份验证后执行的代码,如
但在这种情况下,您需要修改 API,这可以通过使用类别来实现。请参阅 Mike Ash 的这篇博文。他在同一个博客上还有许多关于区块的其他帖子,这些帖子也非常有启发性。
It's a standard practice in Objective-C to put the code to be executed after the authentication in the
authenticationSucess:
method. You might not like it, but that is life.Many people had the same complaint as you, so
on iOS 4 and later, there's something called blocks which allow you to write the code to be executed after the authentication in the method which initiates the authentication, as in
But in this case you need to modify the API, which is possible by using categories. See this blog post by Mike Ash. He has many other posts on blocks on the same blog, which are also very instructive.
如果您要使用异步工作的库(因此不会阻塞您的 UI),那么您应该有充分的理由尝试强制它同步工作。
您应该在
authenticationSuccess:authenticatedWithError:
方法末尾检查身份验证错误,如果成功,则从那里调用下一个请求。同样,在您的spreadsheetsTicket:finishedWithFeed:error:
中检查是否有错误,如果没有错误则继续处理。用单独的方法继续工作可能是更好的设计,但这取决于您。您想要以同步方式使用 GData API 是否有特定原因?
If you're going to use a library that works asynchronously (and therefore doesn't block your UI), you should have a good reason for trying to force it to work synchronously.
You should be checking for an authentication error at the end of your
authenticationSuccess:authenticatedWithError:
method, and calling the next request from there if there's a success. Similarly, in yourspreadsheetsTicket:finishedWithFeed:error:
check for an error, and continuing processing if there isn't one. It might be a better design to do that continued work in a separate method, but that's up to you.Is there a specific reason you want to use the GData API in a synchronous fashion?