我有一个库项目,它使用 ASIHTTPRequest 发出 URL 请求并解析响应。该库将由一个单独的 iPhone 应用程序项目使用。
如果我的 iPhone Controller 代码响应触摸事件,然后调用库来发出 URL 请求,我如何最好地异步执行请求?
在库中,如果我将委托(delegate)模式用于异步请求,如 ASIHTTPRequest 示例代码所示,如何将数据从库返回给 iPhone Controller 中的调用代码?
如果我改为在库中使用 ASIHTTPRequest 发出同步 URL 请求,那么将 iPhone Controller 对库的调用放在单独的线程上以避免占用 UI 线程的最简单方法是什么?
Best Answer-推荐答案 strong>
我不是 ASIHTTPRequest 专家(NSURLRequest 一直做得很好),但是从快速查看代码来看,您似乎会使用它的委托(delegate)和 didFinishSelector 属性来告诉它何时 URL 请求是完成的。所以,例如:
- (void)startURLRequest
{
ASIHTTPRequest *myRequest;
/* code to set the request up with your target URL, etc here */
myRequest.delegate = self;
myRequest.didFinishSelector = @selector(HTTPRequestDidFinish;
/* ... */
[myRequest startAsynchronous];
}
- (void)HTTPRequestDidFinishASIHTTPRequest *)request
{
NSLog(@"Request %@ did finish, got data: %@", request, request.data);
[myTargetForData didReceiveData:request.data fromURL:request.originalURL];
}
Apple 明确建议您使用内置的 runloop 样式机制进行异步 HTTP 获取,而不是使用单独的线程。使用单独的线程可能会导致性能下降 - 至少在电池生命周期和/或设备发热方面,即使它仍然足够快。
也就是说,作为一个学习点,到目前为止,将某些内容切换到单独的线程并将其报告回主线程(请记住:UIKit 对象可能仅从主线程发送消息)的最快方法是通过更改此:
- (void)postResultNSString *)result
{
instanceOfUILabel.text = result;
}
- (void)doExpensiveOperationOnNSString *)source
{
/* lots of expensive processing here, and then... */
[self postResult:result];
}
- (IBAction)userWantsOperationDoneid)sender
{
[self doExpensiveOperationOn"some value or another"];
}
进入这个:
- (void)postResultNSString *)result
{
instanceOfUILabel.text = result;
}
- (void)doExpensiveOperationOnNSString *)source
{
/* we're on a thread without an autorelease pool now, probably we'll want one */
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
/* lots of expensive processing here, and then... */
/* in this simplified example, we assume that ownership of 'result' is here on this thread, possibly on the autorelease pool, so wait until postResult has definitely finished before doing anything that might release result */
[self performSelectorOnMainThreadselector(postResult withObject:result waitUntilDone:YES];
[pool release];
}
- (IBAction)userWantsOperationDoneid)sender
{
[self performSelectorOnBackgroundThreadselector(doExpensiveOperationOn withObject"some value or another"];
}
尽管不考虑线程,但您可能会产生大约一百万个并发错误,在该示例中,一个明显的问题是触发 IBAction 的任何内容都可能 [可能] 在 doExpensiveOperationOn 完成之前再触发几次。多线程不是轻而易举的事情。
关于iphone - iOS 设计 : Using the delegate pattern in a library,我们在Stack Overflow上找到一个类似的问题:
https://stackoverflow.com/questions/3962502/
|