XCode:从另一个文件执行方法后停止动画活动指示器

时间:2013-06-14 07:45:36

标签: ios xcode ios6 nsthread uiactivityindicatorview

好吧,这似乎应该是很简单 - 所有我想要做的就是打电话给我ServerConnect.m(NSObject的),NSURL连接请求的方法,从我SignIn.m(视图控制器)和NSURL请求后停止UIActivityIndi​​catorView已经完成了。当然,如果我在主线程上完成所有操作:

- (IBAction)forgotPassword:(id)sender {    
    [activityIndicator startAnimating];
    connection = [[ServerConnect alloc] init];
    [connection sendUserPassword:email withSecurity:securityID];
    [activityIndicator stopAnimating];
}

然后,所有内容将同时执行,活动指示符将在连接方法完成之前启动和停止...

因此,我尝试将连接请求放在辅助线程上:

- (IBAction)forgotPassword:(id)sender {
    [NSThread detachNewThreadSelector: @selector(requestNewPassword:) toTarget:self withObject:userEmail.text];
}

- (void) requestNewPassword:(NSString *)email
{
    [self->thinkingIndicator performSelectorOnMainThread:@selector(startAnimating) withObject:nil waitUntilDone:NO];

    //Make NSURL Connection to server on secondary thread
    NSString *securityID = [[NSString alloc] init];
    securityID = @"security";
    connection = [[ServerConnect alloc] init];
    [connection sendUserPassword:email withSecurity:securityID];

    [self->thinkingIndicator performSelectorOnMainThread:@selector(stopAnimating) withObject:nil waitUntilDone:NO];
}

但是,我也没有在这里看到活动指标,这可能是由于NSURL请求在辅助线程上无法正常运行(即由于某种原因,它不会收集xml字符串,就像它在主线)。

构建我的代码以使其工作的正确方法是什么?我很惊讶在尝试弄清楚如何让我的活动指示器在另一个文件的一个方法完成执行后简单地停止时,我感到很惊讶。有没有办法串行运行代码(一个接一个)而不是同时运行?任何帮助将不胜感激。

更新为显示:sendUserPassword:(NSString *)withSecurity:(NSString *)

- (void)sendUserPassword:(NSString *)emailString
            withSecurity:(NSString *)passCode;
{
    NSLog(@"Making request for user's password");
    newUser = NO;
    fbUser = NO;
    forgotPassword = YES;
    NSString *post = [NSString stringWithFormat: @"email=%@&s=%@", emailString, passCode];
    NSData *postData = [post dataUsingEncoding:NSUTF8StringEncoding];
    //Construct the web service URL
    NSURL *url = [NSURL URLWithString:@"http://www.someurl.php"];
    //Create a request object with that URL
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url
                                                           cachePolicy:NSURLRequestReloadIgnoringCacheData
                                                       timeoutInterval:90];
    [request setURL:url];
    [request setHTTPMethod:@"POST"];
    [request setHTTPBody:postData];
    //Clear out the existing connection if there is one
    if(connectionInProgress) {
        [connectionInProgress cancel];
    }
    //Instantiate the object to hold all incoming data
    xmlData = [[NSMutableData alloc] init];

    //Create and initiate the conection - non-blocking
    connectionInProgress = [[NSURLConnection alloc] initWithRequest: request
                                                           delegate:self
                                                   startImmediately:YES];
}

3 个答案:

答案 0 :(得分:0)

一个建议尝试这样:

- (IBAction)forgotPassword:(id)sender
{
    [self->thinkingIndicator startAnimating];
    [NSThread detachNewThreadSelector: @selector(requestNewPassword:) toTarget:self withObject:userEmail.text];
}

- (void) requestNewPassword:(NSString *)email
{
    //Make NSURL Connection to server on secondary thread
    NSString *securityID = [[NSString alloc] init];
    securityID = @"security";
    connection = [[ServerConnect alloc] init];
    [connection sendUserPassword:email withSecurity:securityID];

    [self->thinkingIndicator performSelectorOnMainThread:@selector(stopAnimating) withObject:nil waitUntilDone:NO];
}

答案 1 :(得分:0)

我最终加入了NSNotification系统(see Multithreading for iOS)来解决我的问题。任何理由都不赞成这个:

“将代码的一部分更新发送到另一部分的一种简单方法是Apple的内置NSNotification系统。

这很简单。您将获得NSNotificationCenter单例(通过[NSNotificationCenter defaultCenter])和:

1。)如果您要发送更新,请调用postNotificationName。你只需给它一个你编写的唯一字符串(例如“com.razeware.imagegrabber.imageupdated”)和一个对象(例如刚下载完图像的ImageInfo)。

2.。)如果您想知道何时发生此更新,请调用addObserver:selector:name:object。在我们的例子中,ImageListViewController将想知道何时发生这种情况,以便它可以重新加载适当的表视图单元格。放置它的好地方是viewDidLoad。

3。)当视图被卸载时,不要忘记调用removeObserver:name:object。否则,通知系统可能会尝试在卸载的视图上调用方法(或者更糟的是未分配的对象),这将是一件坏事!“

答案 2 :(得分:0)

你可以试试这个,它在完成后会使用一个块。我有类似的事情right here

// Turn indicator on

// Setup the request
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:urlString]];
[request setTimeoutInterval: 90.0];
[request setHTTPMethod:@"POST"];
[request setHTTPBody:postData];
request.cachePolicy = NSURLRequestReturnCacheDataElseLoad;

[NSURLConnection sendAsynchronousRequest:request
              queue:[NSOperationQueue currentQueue]
              completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
              // Its has finished but sort out the result (test for data and HTTP 200 i.e. not 404)
              NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
              if (data != nil && error == nil && [httpResponse statusCode] == 200)
              {

                 // Connection finished a gooden
                 // Do whatever you like with data
                 // Stop indicator

              }
              else
              {
                 // There was an error, alert the user
                 // Do whatever you like with data
                 // Stop indicator

              }

          }];