1

我在使用 NSArrayController rerangeObjects 函数时遇到了问题 - 这个函数是从一些后台踏板调用的,有时应用程序会因错误而崩溃:'endUpdates 调用时没有 beginUpdates'。

我如何检测 arrayController 是否在当前时刻重新排列对象并将下一个重新排列添加到队列或取消当前重新排列并运行新的?

这个问题可能有另一种解决方案吗?

添加了编辑代码:

TableController implementation:

- (void)setContent{//perfoms on main thread
     //making array of content and other functions for setting-up content of table
     //...
     //arrayController contains objects of MyNode class
     //...
     //end of setting up. Call rearrangeObjects
     [arrayController rearrangeObjects];
}

- (void)updateItem:(MyNode *)sender WithValue:(id)someValue ForKey:(NSString *)key{
     [sender setValue:someValue forKey:key];
     [arrayController rearrangeObjects];//exception thrown here
}

MyNode implementation:

- (void)notifySelector:(NSNotification *)notify{
     //Getted after some processing finished
     id someValue = [notify.userInfo objectForKey:@"observedKey"];
     [delegate updateItem:self WithValue:someValue ForKey:@"observedKey"];
}
4

3 回答 3

4

不要那样做。AppKit(NSArrayController属于)通常不是线程安全的。相反,用于-performSelectorOnMainThread:...更新您的 UI(包括NSArrayController)。总是在主线程上进行更新。

于 2012-08-23T17:14:18.177 回答
0

约书亚和丹的解决方案是正确的。您很有可能在后台线程中对模型对象执行操作,然后该线程会触及数组控制器,从而触及表格。

NSTableView 本身不是线程安全的。只需添加“beginUpdates/endUpdates”对就可以暂时避免竞争条件。然而,就像 Fin 指出的那样,出于性能原因进行这对更新可能会很好,但这对崩溃没有帮助。

要查找崩溃的根源,请在代码中添加一些断言 ![NSThread currentThread].mainThread - 特别是在您触摸数组控制器的内容之前的任何地方。这将帮助您隔离问题。或者,继承 NSTableView 并在某个键中添加断言,例如覆盖-numberOfRows(在更改时经常调用)和调用 super.

-corbin
AppKit/NSTableView

于 2016-05-02T15:22:53.370 回答
-1

我通过在我的 UI 初始化开始时添加它来解决这个问题

[myTableView beginUpdates];

然后在持久存储完全加载后的最后:

[myTableView endUpdates];

这也使应用程序启动得更好,因为它不必不断地从 MOC 重新加载所有负载。

于 2013-03-21T13:16:35.410 回答