GCD を使用して別のスレッドでオブジェクト全体を実行する方法はありますか? 別の言い方をすれば、DAO.m を独自のスレッドで実行するにはどうすればよいですか? それらが実行されるオブジェクトに密接にバインドされているいくつかの実行時間の長い操作があります。 詳細: 現在、デバイス (iPad 2) でのアプリケーションの実行を妨げているいくつかの実行時間の長い操作を含む sqlite3 データベースがありますが、それらはシミュレーターで動作します。ただし、メインスレッドをブロックします。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 に答える