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



我做了一个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]]];

您也可以使用NSOperationQueueNSBlockOperation如果您发现GCD困难

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更多信息

这样的问题以前已经被问过几百次了。我建议你快速搜索一下。此外,在apple文档中有一个主题详细介绍了这一领域。

基本上你可以用操作队列或调度队列来做到这一点。上面有一些Avi &阿玛。

我想补充一点,因为你似乎对这个话题不熟悉& &;你提到有web请求。

    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
                     });
                 });
             }];
        });
    });

你可以使用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.
    });
})

但是你需要理解block是如何工作的。试试。

使用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) {
});

});

只在主线程上使用

dispatch_async(dispatch_get_main_queue(), ^(void) {
});

然后释放

dispatch_release(yourDispatch);

有很多方法:

1。中央调度中心

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];

相关内容

最新更新