同步分布式对象在NSConnection连接问题
-
19-09-2019 - |
题
我有从网络中提取数据,解析它们,并编译在搜索接口的结果的应用程序。由于数据不互相依赖的,这是有意义的多线程执行多个取和同时解析该应用程序。我用NSInvocationOperation上的搜索和解析对象我已写入到执行该功能。
在控制器对象我有以下方法:
-(void) searchAndParseAsynchronously {
NSPort *serverPort = [NSMachPort port];
NSConnection *serverConnection = [NSConnection connectionWithReceivePort:serverPort sendPort:serverPort];
[serverConnection setRootObject:self];
for (NSURL *urlToProcess in self.urlsToFetch)
{
BaseSearchParser *searcherForURL = [BaseSearchParser newSearchParserWithParameters:self.searchParams];
searcherForURL.urlToDocument = urlToDocument;
SearchThreader *searchThreader = [SearchThreader new];
searchThreader.threadConnection = comConnection;
searchThreader.targetSchema = searcherForURL;
NSInvocationOperation *threaderOperation = [[NSInvocationOperation alloc] initWithTarget:searchThreader
selector:@selector(executeSearchParse)
object:nil];
[self.operationQueue addOperation:threaderOperation];
}
}
在应用程序依赖于核心数据,我已经收集大部分线程不安全的。我有不同的NSManagedObjectContext为每个搜索/分析操作(和一个用于控制器),并且仅通过操作或代理对象之间的NSManagedObjectId。
的操作经由NSConnection连接对象通信已完成的解析结果返回到他们的控制器。该控制器构造使用NSMachPort对象NSConnection连接,本身设置为根对象,并给出了相同的NSConnection连接对象到每个NSInvocationOperations的目标。然后,控制器在入队用于NSInvocationOperation在其自己的NSOperationQueue执行。
在所述搜索对象穿线我有以下方法:
-(void) executeSearchAndParse
{
id parentServer = [threadConnection rootProxy];
[parentServer setProtocolForProxy:@protocol(SearchParseProtocol)];
NSArray *importResults = [targetSchema generatedDataSetIds];
[parentServer schemaFinished:targetSchema];
[parentServer addSearchResults:importResults];
}
相信我按照给定的此处。
我不得不说,大多数时候,这个精美的作品:从NSConnection连接rootProxy的通知张贴在主线程运行循环的预期,等待皮卡直到控制器对象已准备就绪。然而,在一些的我的测试情况下,它会导致核心数据研磨一个急刹车因为有时消息使其向控制器对象的在相同的线程中被调用rootProxy对象的NSInvocationOperation对象。
我已经放在一个调试点在上消息的控制器当搜索/解析操作是足够完整的,并且肯定,有时其被发送(只是有时)正在执行的线程是不的所述主要原因之一。没有人有一个想法,为什么这可能发生?或者,有没有构建线程间的异步通信更简单的方法?或者是我的核心数据完全平衡度欠佳?
办法提前感谢!
解决方案
我看不出什么毛病你的方法和以前使用过以类似的方式NSConnection
。只有我的事情我看到的是,我只是来替代使用NSPort
明确NSMachPort
。
或者,是否有构建线程间异步通信更简单的方法是什么?
我不认为苹果促进线程间通信ditributed对象了。 IIRC这个猜测主要基于我所看到的文档中提到这确实促进DO用于线程间通信但因为已被删除或编辑。
我也觉得线程相关performSelector:在NSObject的方法是非常容易使用:
- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait
- (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(id)arg waitUntilDone:(BOOL)wait
(而第二个是只可从10.5上)。