我在我的应用中使用[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error)
。通过使用这个我的应用程序在iOS 4.3中终止,但它在iOS 5.0中正常工作。
如何在iOS 4.3中使用它可以帮助我。
答案 0 :(得分:6)
这是一个适合我的完整实现。您可以随意重命名并在NSURLConnection
上添加为类别,或者只是在您正在使用的课程中将其添加为本地方法。
-(void)sendAsynchronousRequest:(NSURLRequest*)request queue:(NSOperationQueue*)queue completionHandler:(void(^)(NSURLResponse *response, NSData *data, NSError *error))handler
{
__block NSURLResponse *response = nil;
__block NSError *error = nil;
__block NSData *data = nil;
// Wrap up synchronous request within a block operation
NSBlockOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:^{
data = [NSURLConnection sendSynchronousRequest:request
returningResponse:&response
error:&error];
}];
// Set completion block
// EDIT: Set completion block, perform on main thread for safety
blockOperation.completionBlock = ^{
// Perform completion on main queue
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
handler(response, data, error);
}];
};
// (or execute completion block on background thread)
// blockOperation.completionBlock = ^{ handler(response, data, error); };
// Execute operation
[queue addOperation:blockOperation];
}
修改强> 的 我必须修改方法,因为我在完成块中进行了UIKit调用(例如更新标签等)。因此,在主线程上调用完成块实际上更安全一些。 (原版注释掉)
答案 1 :(得分:2)
您尝试使用的方法仅适用于iOS 5.对于早期的操作系统,请考虑使用
+ (NSData *)sendSynchronousRequest:(NSURLRequest *)request returningResponse:(NSURLResponse **)response error:(NSError **)error
并将其包装到新线程中以实现异步行为。
答案 2 :(得分:0)
H2CO3 和 Ken Thomases 建议都是正确的。
此外,您可以查看ios4-implementation-of-nsurlconnection-sendasynchronousrequestqueuecompletio。
如果您将主队列用作完成处理程序执行的队列,则可以使用(如 Tom 建议的)委托模式。为避免重复代码,您可以在NSURLConnection
委托机制上使用包装器。
在另一种情况下,如果您想维持异步行为并且您不想处理同步通话(建议 H2CO3 ,请注意他的建议也有效)并完成handler在不同的队列中执行,然后我建议你将异步委托模式包装在NSOperation
类中。这种方法非常困难,但您可以在Concurrent Operations Demystified中找到一种很好的方法(参见这两篇文章)。
希望它有所帮助。