Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cocoa/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c 在次线程中绑定到coredata实体NSArrayController的NSTableView列能否正常工作?_Objective C_Cocoa_Core Data_Nstableview_Nsthread - Fatal编程技术网

Objective c 在次线程中绑定到coredata实体NSArrayController的NSTableView列能否正常工作?

Objective c 在次线程中绑定到coredata实体NSArrayController的NSTableView列能否正常工作?,objective-c,cocoa,core-data,nstableview,nsthread,Objective C,Cocoa,Core Data,Nstableview,Nsthread,我的程序使用Coredata(SQLite)、NSPersistentDocument、NSTableView和(实体)NSArrayController。我希望将主线程中NSTableView的列绑定到在辅助线程中填充的实体NSArrayController 问题1:可能吗?。不幸的是,在我的情况下,它不起作用(通过IB works在同一线程中执行所有操作) 目标是什么:让“获取”(大文档平均完成时间为2-4秒)在辅助线程中运行,这样我就可以在获取时在UI上显示进度指示器 问题2:当实体nsa

我的程序使用Coredata(SQLite)、NSPersistentDocument、NSTableView和(实体)NSArrayController。我希望将主线程中NSTableView的列绑定到在辅助线程中填充的实体NSArrayController

问题1:可能吗?。不幸的是,在我的情况下,它不起作用(通过IB works在同一线程中执行所有操作)

目标是什么:让“获取”(大文档平均完成时间为2-4秒)在辅助线程中运行,这样我就可以在获取时在UI上显示进度指示器

问题2:当实体nsarraycontroller正在安排其数据、获取等时,是否有其他建议的方式显示进度指示器

提前谢谢。 路易斯

然后在我控制我的XIB和所有UI的类中

// ------- ABWindowController.m
:
// Start the secondaryThreadRun in previous class
[[self coredataCtrlTransaction] start];
// Get the pointer to the entity array controller !!! <== HERE!! is it right?
ivOut_CtEn_Transaction = [[self coredataCtrlTransaction]arrayController];

:
// Bind that entity array controller to the NSTableView columns...
if ( [self out_CtEn_Transaction] != nil ) {
    for ( NSTableColumn *column in [[self out_Tableview_Transaction] tableColumns] ) {
        if ( [column identifier] != nil ) {
            if ( [column infoForBinding:@"value"] == nil ) {
                NSString *theKeyPath=nil;
                if ( [[column identifier] length] > 4 )
                    theKeyPath = [[column identifier] substringFromIndex:4];
                else
                    theKeyPath = [column identifier];

                [column bind: @"value" toObject: [self out_CtEn_Transaction]
                 withKeyPath:[NSString stringWithFormat:@"arrangedObjects.%@", theKeyPath] options:nil];
            }
        }
    }
}
/----ABWindowController.m
:
//在上一个类中启动secondaryThreadRun
[[self-coredataCtrlTransaction]启动];
//获取指向实体数组控制器的指针!!!4 )
KeyPath=[[column identifier]substringFromIndex:4];
其他的
keypath=[列标识符];
[列绑定:@“值”对象:[自出交易]
withKeyPath:[NSString stringWithFormat:@“arrangedObjects.%@”,KeyPath]选项:nil];
}
}
}
}

回答我自己,我发现KVO不适合线程间通信,我在主线程中设置了观察器,但在引发键值更改的线程(nsarraycontroller所在的次线程)上接收到了观察结果

因此,如果我的后台线程更改了一个值,我的后台线程将收到关于它的KVO。这是我不想要的

我找到了另一种实现目标的方法,更简单。

找到了关于GDC和

我的目标是:让我展示一个旋转的轮子,而我的“nsarraycontroller正在获取或安排is对象”,在我的例子中,这意味着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];
    });
我怎样才能阻止纺车。这也很简单,我在entity 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];
谢谢 路易斯

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