Coredata& NSPersistentDocument:列号的总和崩溃

时间:2012-11-04 21:59:13

标签: objective-c xcode cocoa core-data nspersistentdocument

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

我正在做一个基于NSPersistentDocument的Coredata程序。我做的大部分都来自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

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

尝试通过“个人资料” - >分配。我注意到了:

  • 我没有内存泄漏
  • 从磁盘加载然后选择all:极其缓慢。 5分钟后还没有完成(我停止了),我看到了+ 45MB的CFNumber(Live Bytes)和> 1.500.00#Overall。所以,这里有些问题,因为我在谈论类型为Interger32的12722行/寄存器。

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

这就是我做label - > Bindings Inspector-> Value

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

请您帮助我了解一下可以帮助我找到问题所在的内容或想法。

非常感谢。

路易斯


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

我找到了一个我不理解的解决方法,请评论/答案真的很感激。

我的程序使用Coredata(SQLite),NSPersistentDocument,NSTableView和NSArrayController。我希望将一个工作的NSTextField绑定到@sum Collection Operation

问题:一旦打开填充了SQLite DB的现有文档,我尝试绑定到NSWindowController中的arrangeObjects。@ sum.t_24_Bookings,程序崩溃。

我最初猜测它与Cannot access contents of an object controller after a nib is loaded有关,但是我遵循了这样的第一个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;

:

ABDocument实施

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

}

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

坦克,
路易斯

1 个答案:

答案 0 :(得分:0)

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

与此同时,我正在创建一个辅助线程,并且我正在从两个不同的线程访问数据模型。正如在Stackoverflow中的几个Q&amp; As中所解释的那样,它非常危险。

我已经在次要线程中创建辅助MOC的几个帖子中应用了注释的解决方案。

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

再次感谢社区。

路易斯