2

我已经为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]]];
4

5 回答 5

3

如果你觉得GCD很困难,你也可以使用NSOperationQueueNSBlockOperation 。

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。查看讨论NSOperationQueueGCD的线程以获取更多信息。

于 2013-04-25T06:25:38.817 回答
1

类似的问题以前被问过数百次。我建议您对此进行快速搜索。苹果文档中也有一个主题彻底涵盖了该领域。这里

基本上你可以用操作队列或调度队列来做到这一点。Avi & Amar 上面给出了一些代码片段。

我想补充一点,因为您似乎不熟悉该主题并且您提到涉及网络请求。

    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
                     });
                 });
             }];
        });
    });
于 2013-04-25T06:38:07.610 回答
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.
    });
})

但是您需要了解块的工作原理。试试看。

于 2013-04-25T06:01:00.410 回答
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);

这里是教程

于 2013-04-25T06:01:59.310 回答
0

有很多方法:

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];
于 2013-04-25T06:12:22.677 回答