我已经为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]]];
答案 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) {
});
});
仅使用
在主线程上执行uidispatch_async(dispatch_get_main_queue(), ^(void) {
});
然后释放它
dispatch_release(yourDispatch);
这是tutorial
答案 4 :(得分:0)
有很多方法:
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];