سؤال

لدي تطبيق يسحب البيانات من الويب، ويقعوها، وتجميع النتائج في واجهة البحث. نظرا لأن البيانات لا تعتمد على التعاون، فمن المنطقي بالتطبيق متعدد الترابط لتنفيذ جدوى متعددة وتبيلاؤها في وقت واحد. يمكنني استخدام NSinVocityoperation على كائن بحث وتحليل كتبته لتنفيذ هذه الوظيفة.

في كائن وحدة التحكم لدي الطريقة التالية:

-(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];
 }
}

يعتمد التطبيق على البيانات الأساسية، والتي جمعتها هي في الغالب موضوع غير آمن. لدي NSMANAGEJONTECTEXTEXTEXTEXTEXT من أجل كل عملية بحث / تحليل (وواحدة لوحدة التحكم)، وتمرير فقط NSManagedobjectid بين العمليات أو الكائنات الوكيلية.

تقوم العمليات بإجراء نتائج التحليل المكتملة مرة أخرى إلى وحدة التحكم الخاصة بها عبر كائن NSConnection. تقوم وحدة التحكم ببناء NSConnection باستخدام كائن NSMachport، ويضع نفسه ككائن جذر، ويعطي نفس كائن NSConnection لكل أهداف من أهداف البائعين. تقوم وحدة التحكم ثم تنزيع NSINVocationoperation للتنفيذ في NSoperationQue الخاص بها.

في كائن Pearch Threader، لدي الطريقة التالية:

-(void) executeSearchAndParse
{ 
 id parentServer = [threadConnection rootProxy];
 [parentServer setProtocolForProxy:@protocol(SearchParseProtocol)];

 NSArray *importResults = [targetSchema generatedDataSetIds];

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

أعتقد أنني قد اتبعت مثال التفاحة على اتصالات عامة موضوعية هنا.

يجب أن أقول أن معظم الوقت، وهذا يعمل بشكل جميل: يتم نشر الإشعارات من NSConnection RootProxy في حلقة التشغيل في الخيط الرئيسي كما هو متوقع وانتظر لالتقاط حتى يكون كائن وحدة التحكم جاهزا. ومع ذلك، في بعض حالات الاختبار الخاصة بي، فإنه يسبب البيانات الأساسية لطحن لوقف الصراخ لأن الرسائل تجعلها في بعض الأحيان إلى كائن وحدة التحكم في نفس الخيط ككائن nsinvocation الذي يدعو كائن RootProxy.

لقد وضعت نقطة مصحح في وحدة التحكم على الرسالة التي يتم إرسالها عند اكتمال عملية البحث / التحليل، وغير متأكد من أنه في بعض الأحيان (فقط أحيانا) هو موضوع تنفيذ ليس الرئيسي. هل لدى أي شخص فكرة عن سبب حدوث ذلك؟ أو، هل هناك طريقة أبسط لبناء الاتصالات غير المتزامنة بين الموضوعات؟ أو هو نهج البيانات الأساسية خارج المنزل تماما؟

شكرا لك مقدما!

هل كانت مفيدة؟

المحلول

لا أرى أي شيء خاطئ في نهجك وتستخدم NSConnection بطريقة مماثلة من قبل. الشيء الوحيد الذي أراه هو أنني استخدمت للتو NSPort بدلا من استخدام NSMachPort صراحة.

أو، هل هناك طريقة أبسط لبناء الاتصالات غير المتزامنة بين الموضوعات؟

لا أعتقد أن Apple تعزز الكائنات المتفجرة للاتصال بين الخيوط المنشأ بعد الآن. IIRC يعتمد هذا التخمين في الغالب على الوثائق التي رأيتها التي شهدتها والتي تعزز حقا DOS للاتصال بين الموضوعات، ولكن منذ ذلك الحين تم إزالتها أو تحريرها.

أعتقد أيضا أن أداء المؤلم: الأساليب على 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 على).

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top