Objective c 在次线程中绑定到coredata实体NSArrayController的NSTableView列能否正常工作?
我的程序使用Coredata(SQLite)、NSPersistentDocument、NSTableView和(实体)NSArrayController。我希望将主线程中NSTableView的列绑定到在辅助线程中填充的实体NSArrayController 问题1:可能吗?。不幸的是,在我的情况下,它不起作用(通过IB works在同一线程中执行所有操作) 目标是什么:让“获取”(大文档平均完成时间为2-4秒)在辅助线程中运行,这样我就可以在获取时在UI上显示进度指示器 问题2:当实体nsarraycontroller正在安排其数据、获取等时,是否有其他建议的方式显示进度指示器 提前谢谢。 路易斯 然后在我控制我的XIB和所有UI的类中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
// ------- 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];