在 iPhone 应用程序中等待异步方法完成如何更好?

发布于 2024-10-05 14:31:20 字数 1946 浏览 5 评论 0原文

大家。 我想了解,当异步方法具有“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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

谈场末日恋爱 2024-10-12 14:31:20

Objective-C 中的标准做法是将身份验证后执行的代码放在 authenticationSucess: 方法中。你可能不喜欢这样,但这就是生活。

很多人和你有同样的抱怨,所以
在 iOS 4 及更高版本上,有一种称为“块”的东西,允许您在启动身份验证的方法中编写要在身份验证后执行的代码,如

[mService authenticateAndExecute:^{ 
                 code to be executed when successfully authenticated ;
          }            whenError:^{
                 code to be executed when authentication failed;
          } ]; 

但在这种情况下,您需要修改 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

[mService authenticateAndExecute:^{ 
                 code to be executed when successfully authenticated ;
          }            whenError:^{
                 code to be executed when authentication failed;
          } ]; 

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.

栖迟 2024-10-12 14:31:20

如果您要使用异步工作的库(因此不会阻塞您的 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 your spreadsheetsTicket: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?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文