0

有没有办法使用 GCD 在单独的线程中运行整个对象?或者换一种说法,我如何在它自己的线程中运行 DAO.m?有一些长时间运行的操作与它们运行的​​对象密切相关。详细信息:我们有一个 sqlite3 数据库,其中包含几个长时间运行的操作,这些操作目前阻止应用程序在设备(iPad 2)上运行,但它们在模拟器中工作-但阻塞主线程。优化 SQL 并不足以提高性能。我们从网上下载文件,处理文件并将结果存入数据库。我们已经异步下载了。

4

2 回答 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 回答