有没有办法使用 GCD 在单独的线程中运行整个对象?或者换一种说法,我如何在它自己的线程中运行 DAO.m?有一些长时间运行的操作与它们运行的对象密切相关。详细信息:我们有一个 sqlite3 数据库,其中包含几个长时间运行的操作,这些操作目前阻止应用程序在设备(iPad 2)上运行,但它们在模拟器中工作-但阻塞主线程。优化 SQL 并不足以提高性能。我们从网上下载文件,处理文件并将结果存入数据库。我们已经异步下载了。
问问题
276 次
2 回答
2
我不确定我的意图是否正确,但这是一个想法 - 您可以子类化NSProxy
以包装您的 DAO 实例并将任何调用转发到它自己的串行队列。像这样的东西(注意,未经测试/编译):
@interface DAOProxy : NSProxy
- (DAO *)initWithDAO:(DAO *)dao;
@end
@implementation DAOProxy {
dispatch_queue_t _daoQueue;
DAO *dao;
}
- (DAO *)initWithDAO:(DAO *)dao {
// no call to [super init] - we are subclassing NSProxy
_dao = dao;
_daoQueue = dispatch_queue_create("com.example.MyDaoQueue", DISPATCH_QUEUE_SERIAL);
return (DAO *)self;
}
- (BOOL)respondsToSelector:(SEL)aSelector {
return [_dao respondsToSelector:aSelector];
}
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector {
return [_dao methodSignatureForSelector:aSelector];
}
- (void)forwardInvocation:(NSInvocation *)anInvocation {
dispatch_async(_daoQueue, ^{
[anInvocation setTarget:_dao];
[anInvocation invoke];
});
}
@end
和用法:
DAO *realDao = ...;
DAO *proxiedDao = [[DAOProxy alloc] initWithDAO:realDao];
// use proxiedDao as you would use the real one from there
如果您想获得 DAO 方法的返回结果,则需要一些额外的技巧,例如在结果准备好时传递回调块以在调用者线程中执行它们......嗯,这是您遇到的异步问题。
于 2013-02-16T01:44:07.310 回答
0
这就是我最终做的。多亏了一位同事和NSURLConnection 和盛大的中央调度。
我并不真的需要将 URL 连接放在块中,但我需要异步处理响应。
[AsyncURLConnection request:pathToProducts url:getProductsURL completeBlock:^(NSData *data) {
/* success! */
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
dAO = [DAO getInstance];
/* do processing here */
dispatch_async(dispatch_get_main_queue(), ^{
/* update UI on Main Thread */
});
});
} errorBlock:^(NSError *error) {
NSLog(@"Well that sucked!");
}];
于 2013-02-16T15:59:31.727 回答