首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >NSConnection上的同步分布式对象问题

NSConnection上的同步分布式对象问题
EN

Stack Overflow用户
提问于 2009-12-11 12:14:09
回答 1查看 1.2K关注 0票数 1

我有一个应用程序,可以从网络中提取数据,解析数据,并在搜索界面中编译结果。由于数据不相互依赖,因此多线程应用程序同时执行多个获取和分析是有意义的。我在我编写的搜索和解析对象上使用NSInvocationOperation来执行这个函数。

在控制器对象中,我有以下方法:

代码语言:javascript
复制
-(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];
 }
}

应用程序依赖于Core数据,我收集到的这些数据大多是线程不安全的。对于每个搜索/解析操作,我都有一个不同的NSManagedObjectContext (一个用于控制器),并且只在操作或代理对象之间传递NSManagedObjectId。

这些操作通过NSConnection对象将完成的解析结果传递给它们的控制器。控制器使用一个NSConnection对象构造NSMachPort,将自身设置为根对象,并向NSInvocationOperations的每个目标提供相同的NSConnection对象。然后控制器将NSInvocationOperation排在队列中,以便在其自己的NSOperationQueue中执行。

在搜索线程对象中,我有以下方法:

代码语言:javascript
复制
-(void) executeSearchAndParse
{ 
 id parentServer = [threadConnection rootProxy];
 [parentServer setProtocolForProxy:@protocol(SearchParseProtocol)];

 NSArray *importResults = [targetSchema generatedDataSetIds];

 [parentServer schemaFinished:targetSchema];
 [parentServer addSearchResults:importResults];
}

我相信我已经遵循了苹果的例子,通用的线程间通信给这里

我不得不说,在大多数情况下,这是非常有效的:来自NSConnection rootProxy的通知按预期的方式发布到主线程中的run循环中,直到控制器对象准备就绪。但是,在我的一些测试用例中,它会导致核心数据停止运行,因为有时消息会在与调用NSInvocationOperation对象的rootProxy对象相同的线程中发送给控制器对象。

我已经在控制器中放置了一个调试器点,当搜索/解析操作完成时,该消息将被发送,并且足够肯定的是,有时(只是有时)执行线程不是主线程。有人知道为什么会发生这种情况吗?或者,是否有一种更简单的方法来构造线程间异步通信?还是我对核心数据的处理方法完全偏离了平衡?

提前感谢!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2009-12-11 13:33:41

我不认为您的方法有任何问题,并且以前使用过类似的NSConnection。我唯一看到的就是我只是使用NSPort而不是显式地使用NSMachPort

或者,是否有一种更简单的方法来构造线程间异步通信?

我不认为苹果正在为线程间的通信推广分布式对象。IIRC这个猜测主要是基于我所见过的文档,这些文档确实促进了线程间通信的DOs,但是从那以后已经被删除或编辑了。

我还认为与线程相关的performSelector: NSObject方法更易于使用:

代码语言:javascript
复制
- (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开始)。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1887687

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档