为什么NSOperationQueue不执行使用addOperationWithBlock提交的块?

时间:2014-09-01 15:40:45

标签: ios objective-c nsoperationqueue viewdidload nsurlsession

这是我得到的一些代码,它没有执行(编译器运行代码但没有做任何事情)......这是代码......使用NSURLSessionDelegate和{{1} }

[NSOperationQueue mainQueue] addOperationWithBlock

更新

另一个代码将方法放入队列......

@interface tablaPosViewController : UIViewController  <NSURLSessionDelegate>

@end

@implementation tablaPosViewController ()

- (void)viewDidLoad
{
//some code to set the view, labels and stuff

[self downloadTheHTMLdata] // this code download some data from WWW

}

- (void)downloadTheHMTLdata
{
//some code to set the session using an object

[object.downloadTask resume]; //Begins the download

}

- (void)toFixTablaPosiciones
{
//some code to do with the downloaded data from WWW (and HTML sheet)
//here, parse the HTML Sheet, and put some data into an Arrays, and another public vars

//call another method
[self PutTheDataInLabel];

}

- (void)PutTheDataInLabel
{
//some code to put all the data in every label
//take the public vars that was set in the previous method, and do some code with it
//and put the info into the labels

//call another method
[self MoreStuff];

}

- (void)MoreStuff
{

//some code..

}


-(void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location
{
    //When the download finish this method fire up!

    //this is to copy file from tmp folder to Docs folder
    if ([fileManager fileExistsAtPath:[destinationURL path]])
    {
        [fileManager removeItemAtURL:destinationURL error:nil];
    }
    BOOL success = [fileManager copyItemAtURL:location       //TMP download folder
                                        toURL:destinationURL //Documents folder 
                                        error:&error];
     //HERES COMES THE TROUBLE!!!
        [[NSOperationQueue mainQueue] addOperationWithBlock:^{
            [self toFixTablaPosiciones]; //Call this method, that has other method calls!
         }];

}
@end

问题是当下载文件结束时,调用-(void)URLSessionDidFinishEventsForBackgroundURLSession:(NSURLSession *)session{ AppDelegate *appDelegate = [UIApplication sharedApplication].delegate; [self.session getTasksWithCompletionHandler:^(NSArray *dataTasks, NSArray *uploadTasks, NSArray *downloadTasks) { if ([downloadTasks count] == 0) { if (appDelegate.backgroundTransferCompletionHandler != nil) { void(^completionHandler)() = appDelegate.backgroundTransferCompletionHandler; appDelegate.backgroundTransferCompletionHandler = nil; [[NSOperationQueue mainQueue] addOperationWithBlock:^{ completionHandler(); }]; } } }]; } 方法并等待-(void)URLSession:(NSURLSession *)session downloadTask:...运行所有内容......但它不会执行任何[[NSOperationQueue mainQueue] addOperationWithBlock:^{... !!

我一步一步地运行代码,我看到编译器如何运行所有代码,方法超过方法......但是视图永远不会更新,运行但不执行,只是做了什么,我有一个活动指示器并希望阻止它,但是lablels仍然使用de dummie数据并且活动指示器永远不会停止并且永远不会消失。 在之前的视图中,我使用类似的类下载另一个文件,并且下载速度非常快。去这个视图/类尝试执行下载,这就是......

希望任何人都可以帮助我并给我任何建议。谢谢!

1 个答案:

答案 0 :(得分:1)

我使用的一种技术,就像大多数有经验的开发人员一样,是使用断言以及NSLog(您可以评论和关闭)来验证您对代码的假设实际上是正确的。尝试剪切并粘贴下面的代码,看看会发生什么 - 它应该有所帮助。将来,不要把头撞在墙上 - 开始添加断言和日志。在某些时候,你会发现某些假设是不真实的。

-(void)URLSessionDidFinishEventsForBackgroundURLSession:(NSURLSession *)session {
    NSLog(@"Received URLSessionDidFinishEventsForBackgroundURLSession: application state is %d", [UIApplication sharedApplication] applicationState];
    AppDelegate *appDelegate = [UIApplication sharedApplication].delegate;

    [self.session getTasksWithCompletionHandler:^(NSArray *dataTasks, NSArray *uploadTasks, NSArray *downloadTasks) {
        NSLog(@"Download task count %d", [downloadTasks count]);
#warning "This looks like incorrect logic, but I don't know this background code. Wouldn't you see "1", or more? Won't you get an array of the tasks you submitted???
        if ([downloadTasks count] == 0) {
            assert(appDelegate.backgroundTransferCompletionHandler); // if this is nil, your app will be stuck in some odd state forever, so treat this like a fatal error
            void(^completionHandler)() = appDelegate.backgroundTransferCompletionHandler;
            appDelegate.backgroundTransferCompletionHandler = nil;

            assert([NSOperationQueue mainQueue]);   // why not?
            assert(![NSOperationQueue mainQueue].isSuspended);  // I looked at the class description, the queue **could** be suspended
            [[NSOperationQueue mainQueue] addOperationWithBlock:^{
                NSLog(@"Completion Operation called!");
                assert(completionHandler);  // perhaps an ARC bug, unlikely, but then you cannot get this code to work, right?
                completionHandler();
            }];
        }
    }];
}