2

我的程序中的列的@sum 绑定有问题:

我正在做一个基于 Coredata、NSPersistentDocument 的程序。我主要从 IB 做所有事情,创建数据模型、NSArrayController 和 NSTableView ......

我只有 1 个具有 62 个属性(61 个 NSString 和 1 个 NSNumber)的实体。我导入了一个包含 12722 条记录的 CSV 文件。导入效果很好,可以保存到 xml、二进制、sqlite...我已经仔细检查了整个过程是否完美。可以保存/加载。一切都在那里。

我遇到的问题:我创建了一个标签,我将其绑定到具有 NSNumber 属性的列的@sum。我就是这样做的

>     label->Bindings Inspector->Value
>      Bind to: My_Entity_NSArrayController
>       Controller Key: selection
>       Model Key Path: @sum.myNumericAttribute

当我运行程序时,单击导入,选择所有行,@sum 运行良好。它很快,但是这是第一个问题:一旦我保存文件(尝试了所有... binary/xml/sqlite)并稍后加载它并尝试再次选择全部,程序崩溃而没有错误

通过“配置文件”-> 分配尝试。我注意到:

  • 我没有内存泄漏
  • 从磁盘加载然后全选时:速度非常慢。5 分钟后还没有完成(我停止了它),我看到了 +45MB 的 CFNumber(实时字节)和 >1.500.00#Overall。所以,这里出了点问题,因为我说的是 12722 行/Interger32 类型的寄存器。

第二个问题是相同的,但从不同的角度再现。我没有使用“选择”,而是尝试使用“arrangedObjects”。在这种情况下,即使从 CSV 导入也会出现问题,它变得非常缓慢,最终崩溃。尝试打开已经创建的文件也会崩溃。

这就是我做标签->绑定检查器->值的方式

>    label->Bindings Inspector->Value
>      Bind to: My_Entity_NSArrayController
>       Controller Key: arrangedObjects
>       Model Key Path: @sum.myNumericAttribute

您能否帮助我了解要查找的内容或可以帮助我找到问题所在的想法?

非常感谢。

路易斯


---- 更多研究后的新编辑 ----

我找到了一个我不理解的解决方法,请评论/回答非常感谢。

我的程序使用 Coredata (SQLite)、NSPersistentDocument、NSTableView 和 NSArrayController。我想让一个工作的 NSTextField 绑定到 @sum 集合操作

问题:只要我打开一个填充了 SQLite DB 的现有文档,并尝试从 NSWindowController 绑定到排列对象。@sum.t_24_Bookings,程序就会崩溃。

我最初的猜测与加载 nib 后无法访问对象控制器的内容有关,但是我遵循了执行第一次 Fetch 的建议,但没有成功:

- (void) awakeFromNib
{
    :
    BOOL ok = [[self out_CtEn_Transaction] fetchWithRequest:nil merge:NO error:&error];
    :

继续这个想法,我发现如果我创建一个“真正的”完整 Fetch + 我从 Document 子类执行 @sum 访问,那么它就可以工作。

这是我为了使解决方法起作用而放置的带有注释的代码。

ABDocument 接口(一个 NSPersistentDocument 子类)

@interface ABDocument : NSPersistentDocument {

    BOOL        ivNewDocument;
    NSArray     *ivFetchedTransactions;
    NSNumber    *ivTotalBookings;
}

@property (nonatomic, getter=isNewDocument) BOOL newDocument;
@property (nonatomic, retain) NSArray   *fetchedTransactions;
@property (nonatomic, retain) NSNumber  *totalBookings;

:

AB文档实施

#import "ABDocument.h"
#import "ABWindowController.h"

@implementation ABDocument

@synthesize newDocument                 = ivNewDocument;
@synthesize totalBookings               = ivTotalBookings;
@synthesize fetchedTransactions         = ivFetchedTransactions;

:

/** @brief Create one instance of my custom NSWindowController subclass (ABWindowController)
 *
 * In my NSPersistentDocument I do override makeWindowControllers, where I create 
 * one instance of my custom NSWindowController subclass and use addWindowController: 
 * to add it to the document. 
 *
 */
- (void) makeWindowControllers
{
    // Existing Document?
    if ( ![self isNewDocument]) {
        // NSLog(@"%@:%@ OPENING EXISTING DOCUMENT", [self class], NSStringFromSelector(_cmd));

        // Opening existing document (also has an existing DDBB (SQLite)), so
        // make sure I do perform a first complete "fetch + @sum" to void issues
        // with my NIB bind's.
        [self firstFetchPreventsProblems];
    }

    // Now I can create the Window Controller using my "MainWindow.xib".
    ABWindowController *windowController = [[ABWindowController alloc] init];
    [self addWindowController:windowController];
    [windowController release];    
}


/** @brief First complete "fetch + @sum" to void issues with my NIB bind's.
 *
 *  Before I create the Window Controller with "MainWindow.xib" I have to perform a
 *  first Fetch AND also retrieve a @sum of an NSNumber column.
 *
 *  My NIB has an NSTextField BOUND to @arrangedObjects.@sum.<property> through a NSArrayController
 *  If I don't call this method before the NIB is loaded, then the program will crash.
 *
 */
- (void) firstFetchPreventsProblems {

    // Prepare the Fetch
    NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Transaction"];

    // 1) Perform the Fetch
    NSError *error = nil;
    [self setFetchedTransactions:[[self managedObjectContext ] executeFetchRequest:request error:&error]];
    if ([self fetchedTransactions] == nil)
    {
        NSLog(@"Error while fetching\n%@",
              ([error localizedDescription] != nil) ? [error localizedDescription] : @"Unknown Error");
        exit(1);
    }

    // 2) Execute Collection Operation @sum
    [self setTotalBookings:[[self fetchedTransactions] valueForKeyPath:@"@sum.t_24_Bookings"]];
}

ABWindowController(加载我的NIB的控制器)

- (void)windowDidLoad
{

:
        // PROGRAM CRASH HERE 
        // IF [self firstFetchToPreventsProblems]; is NOT CALLED
        // ABDocument's "makeWindowControllers:"
       [[self totalSumField] bind: @"value" toObject: [self out_CtEn_Transaction]
                       withKeyPath:@"arrangedObjects.@sum.t_24_Bookings" options:nil];

}

请如果你能评论真的很感激,我有一个解决方案,但我不明白为什么。

坦克,
路易斯

4

1 回答 1

0

经过几天的研究,我自己发现了这个问题。这很容易(现在我知道了):

与此同时,我正在创建一个辅助线程,并且碰巧我正在从两个不同的线程访问数据模型。正如 Stackoverflow 的几个问答中所解释的那样,这是非常危险的。

我已经将评论的解决方案应用于在辅助线程中创建辅助 MOC 的几篇文章中。

现在我的代码根据与 coredata 相关的操作是线程安全的,因此程序不会崩溃。

再次感谢社区。

路易斯

于 2012-11-30T20:27:17.233 回答