2012-11-30 61 views
0

我的程序使用Coredata(SQLite),NSPersistentDocument,NSTableView和(實體)NSArrayController。我希望主線程中的NSTableView的列綁定到實體NSArrayController,我已經在輔助線程中填充了這些列。NSTableView列可以在輔助線程中綁定到coredata實體NSArrayController嗎?

問題1:有可能嗎?不幸的是沒有在我的情況下工作(同時通過IB作品在同一線程中做所有事情)

目標是什麼:讓「fetch's」(大文檔平均值爲2-4秒完成)抓取時,我可以在UI上顯示進度指示器。

問題2:當實體nsarraycontroller正在安排其數據,獲取等等時,是否有任何其他推薦方法顯示進度指示符?

在此先感謝。 路易斯

// ------- ABCoredataController.h 
@interface ABCoredataController : NSObject { 
: 
    NSArrayController    *ivArrayController; 
} 
@property (nonatomic, assign) NSArrayController *arrayController; 


// ------- ABCoredataController.m 

// This piece executes in Main thread... 
- (void) init { 
    ivArrayController = [[NSArrayController alloc] init]; 
: 


// Following is later executed in the Secondary Thread 
- (void) secondaryThreadRun:(id)param { 
    : 
    // prepare everything to access coredata from a secondary thread... 
    [self setSecondaryThreadMOC: [[[NSManagedObjectContext alloc]init] autorelease] ]; 
    [[self secondaryThreadMOC] setPersistentStoreCoordinator:[self mainThreadPSC]]; 

    // prepare the (entity) array controller 
    [[self arrayController] setAvoidsEmptySelection:YES]; 
    [[self arrayController] setPreservesSelection:YES]; 
    [[self arrayController] setSelectsInsertedObjects:YES]; 
    [[self arrayController] setClearsFilterPredicateOnInsertion:YES]; 
    [[self arrayController] setAutomaticallyPreparesContent:YES]; 
    [[self arrayController] setAutomaticallyRearrangesObjects:YES]; 
    [[self arrayController] setAlwaysUsesMultipleValuesMarker:NO]; 
    [[self arrayController] setUsesLazyFetching:NO]; 
    [[self arrayController] setEditable:YES]; 
    [[self arrayController] setEntityName:@"Transaction"]; 

    // bind arrayController to the managedObjectContext 
    [[self arrayController] setManagedObjectContext:[self secondaryThreadMOC]]; 
    [[self arrayController] setFilterPredicate:[self predicate]]; 

    : 

然後在那裏我控制我的廈門國際銀行和所有的UI類裏面...

​​3210

回答

0

回答我自己,我發現,志願是沒有良好的間通信,我m將觀察者設置在MainThread中,但觀察在源自鍵值變化的線程上接收(nsarraycontroller所在的輔助線程)。因此,如果我的後臺線程更改了一個值,我的後臺線程將接收關於它的KVO。這是我不想要的東西。

Found good comment about it here:

我發現我實現目標的另一種方式,更簡單。在GDC here

找到很好的例子here

我的目標是:讓我告訴一個紡輪,而我的「NSArrayController的取指或安排爲對象」,這在我的情況下,意味着2-3秒。

// Last step in the preparation of the predicate 
    NSPredicate *predicadoFinal = nil; 
    predicadoFinal = [NSCompoundPredicate andPredicateWithSubpredicates:array_AND_Total]; 

    // Use GCD (Grand Central Dispatch) to be able to show the spinning wheel 
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); 
    dispatch_async(queue, ^{ 
     dispatch_async(dispatch_get_main_queue(), ^{ 
      // Do here my stuff of showing in the UI something... 
      [[self out_ABSpinning_DDBB] setHidden:NO]; 
      [[self out_ABSpinning_DDBB] startAnimation:self]; 
     }); 
     // And here CPU consuming stuff. 
     // Apply the predicate to the nsarraycontroller. 
     // As the controller has both setAutomaticallyPreparesContent:YES 
     // and setAutomaticallyRearrangesObjects:YES so setting 
     // the predicate will automatically trigger the controller 
     // to process the predicate and fetch again... 
     [self setPredicateFINAL:predicadoFinal]; 
    }); 

如何停止紡車。它也很容易,我設置一個觀察者對實體NSArrayController的是這樣的:

if (nil == ivObservableKeysABCtEn_Transaction) { 
    ivObservableKeysABCtEn_Transaction = [[NSSet alloc] initWithObjects: 
              @"arrangedObjects", 
              nil]; 
} 
: 

if ([self out_CtEn_Transaction] != nil) { 

    for (NSString *keyPath in [self observableKeysABCtEn_Transaction]) { 

     // Añado observers para cada uno de los keyPaths en los que estoy interesado 
     [[self out_CtEn_Transaction] addObserver:self 
        forKeyPath:keyPath 
         options:0 
         context:ABObserverABCtEn_Transaction]; 
    } 
} 

然後在:

- (void)observeValueForKeyPath:(NSString *)keyPath 
         ofObject:(id)object 
         change:(NSDictionary *)change 
         context:(void *)context 
{ 
    // Fetch del objeto que ha cambiado en el emisor. En mi caso un BOOL 
    id newChange = [change objectForKey:NSKeyValueChangeNewKey]; 

    // Detect null's 
    if ([NSNull null] == (NSNull*)newChange) { 
     newChange = nil; 
    } else { 
    : 
     // 
     // Somthing has changed in the "arrangedObjects" property 
     // of my coredata array controller, so it has definitely 
     // finished doing its work. 
     if (context == ABObserverABCtEn_Transaction) { 
      [[self out_ABSpinning_DDBB] stopAnimation:self]; 
      [[self out_ABSpinning_DDBB] setHidden:YES]; 

感謝 路易斯

相關問題