如何在应用程序的后台运行一个不会影响我的应用程序用户界面的线程

时间:2013-04-25 05:54:51

标签: iphone ios objective-c ipad xcode4.6

我已经为IOS做了一个应用程序,其中我使用的是sqlite数据库,数据库在应用程序中是本地的。 现在我已经给出了应用程序从互联网上下载数据的功能。把它放在本地数据库&显示用户面前。我在- (void)viewDidLoad上给出了这个功能,这样当应用程序下载数据时,它会停止工作直到完成下载部分,因此该用户需要等待与应用程序交互。

现在我想在应用程序的后台运行一个线程,它将连接互联网和放大器。更新应用程序而不会干扰用户。 请帮帮我。

我的下载代码&保存图片是这样的:

 -(void)Download_save_images:(NSString *)imagesURLPath :(NSString *)image_name   
   {                              

      NSMutableString *theString = [NSMutableString string];

    // Get an image from the URL below    
      UIImage *image = [[UIImage alloc] initWithData:[NSData dataWithContentsOfURL:NSURL  URLWithString:imagesURLPath]]];        
      NSLog(@"%f,%f",image.size.width,image.size.height);        
     NSString *docDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];

    // If you go to the folder below, you will find those pictures
     NSLog(@"%@",docDir);    
    [theString appendString:@"%@/"];
    [theString appendString:image_name];
    NSLog(@"%@",theString);
    NSLog(@"saving png");
    NSString *pngFilePath = [NSString stringWithFormat:theString,docDir];
    NSData *data1 = [NSData dataWithData:UIImagePNGRepresentation(image)];
    [data1 writeToFile:pngFilePath atomically:YES];  

    NSLog(@"saving image done");

    [image release];
   // [theString release];
}

当我调试应用程序时,我看到我的应用程序在下面的行中花费了更多时间:

UIImage *image = [[UIImage alloc] initWithData:[NSData dataWithContentsOfURL:NSURL  URLWithString:imagesURLPath]]];

5 个答案:

答案 0 :(得分:3)

如果您发现 GCD 很困难,也可以使用 NSOperationQueue NSBlockOperation

NSBlockOperation *operation=[[NSBlockOperation alloc] init];

[operation addExecutionBlock:^{
    //Your code goes here

}];

NSOperationQueue *queue=[[NSOperationQueue alloc] init];
[queue addOperation:operation];

GCD 中您可以使用

实现相同目标
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
   //Your Code to download goes here

    dispatch_async(dispatch_get_main_queue(), ^{
       //your code to update UI if any goes here

    });
});

根据您的需要使用任一API。请查看此讨论NSOperationQueue vs GCD的帖子以获取更多信息。

答案 1 :(得分:1)

此类问题曾被问过数百次。我建议你快速搜索一下。此外,苹果文档中还有一个主题,涵盖了该领域。 here

基本上,您可以使用操作队列或调度队列执行此操作。 Avi& Co.提供了一些上面给出的代码片段。阿马尔。

我想添加一些东西,因为你似乎不熟悉这个主题&你提到有网络请求参与。

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{

    // Dont DIRECTLY request your NSURL Connection in this part because it will never return data to the delegate...
//  Remember your network requests like NSURLConnections must be invoked in mainqueue
// So what ever method you're invoking for NSURLConnection it should be on the main queue

        dispatch_async(dispatch_get_main_queue(), ^{
                // this will run in main thread. update your UI here.
        });
    });

我在下面给出了一个小例子。您可以概括出符合您需求的想法。

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{

        // Do your background work here

        // Your network request must be on main queue. this can be raw code like this or method. which ever it is same scenario. 
        NSURLRequest *req = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.google.com"]];
        dispatch_async(dispatch_get_main_queue(), ^{

            [NSURLConnection sendAsynchronousRequest:req queue:[NSOperationQueue currentQueue] completionHandler:^(NSURLResponse *res, NSData *dat, NSError *err)
             {
                 // procress data

                 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{

                     // back ground work after network data received

                     dispatch_async(dispatch_get_main_queue(), ^{

                         // finally update UI
                     });
                 });
             }];
        });
    });

答案 2 :(得分:0)

你可以像我们那样使用GCD:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
    // put here your background code. This will run in background thread.

    dispatch_async(dispatch_get_main_queue(), ^{
            // this will run in main thread. update your UI here.
    });
})

但是你需要了解块的工作原理。试试吧。

答案 3 :(得分:0)

使用GCD

创建您的调度对象

dispatch_queue_t yourDispatch;
yourDispatch=dispatch_queue_create("makeSlideFast",nil);

然后使用它

dispatch_async(yourDispatch,^{
//your code here

//use this to make uichanges on main thread
dispatch_async(dispatch_get_main_queue(), ^(void) {
});


});

仅使用

在主线程上执行ui
dispatch_async(dispatch_get_main_queue(), ^(void) {
});

然后释放它

dispatch_release(yourDispatch);

这是tutorial

答案 4 :(得分:0)

有很多方法:

1。 Grand Central Dispatch

dispatch_async(dispatch_get_global_queue(0, 0), ^{
  //Your code
});

2。 NSThread

[NSThread detachNewThreadSelector:@selector(yourMethod:) toTarget:self withObject:parameterArray];

3。 NSObject - performSelectorInBackground

[self performSelectorInBackground:@selector(yourMethod:) withObject:parameterArray];