我刚开始在iOS上编程,我需要构建将从Web服务器下载一些文件的应用程序,并在执行此操作时更新状态栏,但我不希望我的应用程序冻结,因此用户仍然可以在应用程序上执行其他操作。有什么想法?。
答案 0 :(得分:2)
iOS有一个内置的异步(即非阻塞)HTTP客户端类。
构造一个NSURLConnection
对象。提供请求参数,提供委托,调用[start]。该文件将开始下载,但该应用程序和手机的其余部分不会被冻结。您可以随时更新状态栏。
委托类方法必须收集传入数据并处理完成。
答案 1 :(得分:0)
最常见的网络任务(包括图像请求,JSON拉动等)实际上可以通过优秀的AFNetworking library非常轻松地异步实现。
示例请求:
-(void) startDownloadOfSomeFiles
{
NSURLRequest* request = [NSURLRequest requestWithURL: [NSURL URLWithString:@"http://example.com/a_file.zip"]];
AFHTTPRequestOperation* operation = [[AFHTTPRequestOperation alloc] initWithRequest: request];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
// Request was successful.
NSString* path = ....
operation.outputStream = [NSOutputStream outputStreamToFileAtPath:path append:NO];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
// Network request failed. Bummer.
}];
[operation start];
}
至于更新进度条,你必须在主线程上这样做:
[NSOperationQueue mainQueue] addOperationWithBlock:^{
aProgressBar.progress++; // or whatever
}];
例如,这可以在您的请求成功块中完成。
所有与UI相关的东西都必须在iOS的主线程上发生。 [NSOperationQueue mainQueue]允许您向队列添加操作。更多关于这一点。如果您尝试从后台NSOperation更新UI元素,您的应用很可能会崩溃。
如果您对一般的线程感兴趣,使用后台线程的最简单方法是使用您自己的NSOperationQueue(这也是AFNetworking在幕后进行操作的方式)。您可以使用标准的alloc / init创建自己的NSOperationQueue,并可以在其上设置以下属性:
NSOperationQueue* myOperationQueue = [[NSOperationQueue alloc] init];
myOperationQueue.maxConcurrentOperationCount = 1; //or 2, 3, whatever
这使您可以灵活地使用 addOperation 方法将任务排入队列。您可以子类 NSOperation ,或者,对于较轻的任务,您可以使用
[myOperationQueue addWithBlock:^{
NSLog(@"I'm running in a background thread!");
}];
NSOperationQueue将根据您为其分配的最大线程数,对您在其管理的工作线程上按顺序执行的操作进行排队。如果没有线程在等待,它会在您排队后立即开始执行操作;如果有线程在等待,它将排队并在工作线程空闲后立即启动。
[NSOperationQueue mainQueue] 遵循与上述相同的指导原则。你真正在做的是访问iOS用于你的UI的操作队列(这就是为什么在它上面添加长时间运行的东西是一个非常糟糕的主意 - 你将冻结你的应用程序,因为你有效地运行你的代码同步)。您无法更改主队列上的并发操作数,但您可以将与UI相关的任务排入其中,如上所述。
希望这可以让您深入了解基本面。
答案 2 :(得分:0)
使用多线程。 你也可以使用调度队列。比我见过的其他东西容易得多。 如果您听说过目标c块,它会将其用作基本的c api。
dispatch_queue_t myCustomQueue;
myCustomQueue = dispatch_queue_create("com.example.MyCustomQueue", NULL);
// put work here for separate thread
dispatch_async(myCustomQueue, ^{
printf("Do some work here.\n");
dispatch_async(dispatch_get_main_queue(), ^{
// do stuff in the main thread
}
});
请注意,必须在主线程中调用所有UI Kit函数。 所有后台工作都在其他队列中。
祝你好运,也是开发人员的指导。 https://developer.apple.com/library/ios/documentation/General/Conceptual/ConcurrencyProgrammingGuide/OperationQueues/OperationQueues.html`