2012-11-04 2 views
2

У меня есть проблема с @sum связывания колонки в моей программе:CoreData & NSPersistentDocument: Сумма чисел столбцов грохота

Я делаю программу, основанную CoreData, NSPersistentDocument. Я делаю в основном все от IB, создание модели данных, NSArrayController и NSTableView ...

У меня есть только 1 объект с 62 атрибутами (61 NSString и 1 NSNumber). Я импортирую CSV-файл с 12722 записями. Импорт работает хорошо, можно сохранить в xml, binary, sqlite ... Я дважды проверил, что весь процесс работает отлично. Может сохранять/загружать. Все есть.

Проблема, которая у меня есть: я создал ярлык, который я BIND для @sum столбца с свойством NSNumber. Это, как я сделал

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

Когда я запускаю программу, нажмите на импорт, выберите все строки, то @sum работает хорошо. Это быстро, однако, и вот первая проблема: однажды я сохраню файл (попробовал все ... binary/xml/sqlite), а позже загрузите его и попробуйте снова выбрать ВСЕ, сбой программы без ошибок.

Пробовали через «Профиль» -> Распределение. Я заметил:

  • У меня нет утечек памяти
  • При загрузке с диска, а затем выбрать все: Идет Extremelly медленно. Через 5 минут еще не закончил (я остановил его), и я увидел + 45 МБ CFNumber (Live Bytes) и> 1.500.00 # в целом. Итак, здесь что-то не так, поскольку я говорю о 12722 строках/регистрах типа Interger32.

Вторая проблема такая же, но воспроизведена под другим углом. Вместо того, чтобы использовать «выбор», я попытался использовать «builtObjects». В этом случае проблема возникает даже при импорте из CSV, она идет очень медленно и, наконец, сбой. Пытается открыть уже созданный файл.

Это, как я label-> Наручники Inspector-> Значение

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

Можете ли вы помочь мне с какой-то свет на то, чтобы искать или идеи, которые могут помочь мне найти, где проблема ?.

Большое спасибо.

Луис


---- правка после более RESEARCH ----

Я нашел обходной путь, который я «не понимаю, пожалуйста, комментарии/ответы действительно оценили.

В моей программе используются Coredata (SQLite), NSPsistentDocument, NSTableView и NSArrayController. Я хочу иметь рабочий NSTextField, связанный с операцией по сборке @sum

Проблема: как только я открою существующий документ с SQLite DB, и я попытаюсь привязать его к упорядоченным объектам. @ Sum.t_24_Книги из NSWindowController, крах программы.

Моя первоначальная догадка, что это связанно с 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]; 
    : 

Продолжает с этой идеей, я обнаружил, что если я создаю " real "complete Fetch + Я выполняю доступ @sum из подкласса Document, а затем он работает.

Вот код с комментариями, которые я установил для того, чтобы обходной путь работал.

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 @[email protected]<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 (Контроллер, который загружает мой СИБ)

- (void)windowDidLoad 
{ 

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

} 

Пожалуйста, если вы можете прокомментировать действительно оцененный, у меня есть решение, но я не понимаю, почему.

Танки,
Луис

ответ

0

Я нашел эту проблему сам после того, как несколько дней исследования. Это было легко (теперь, когда я знаю):

Параллельно я создавал вторичный поток и случался, что я обращался к модели данных из двух разных потоков. Как было объяснено в нескольких Q & Как здесь, в Stackoverflow, это очень опасно.

Я применил прокомментированные решения в нескольких сообщениях о создании вторичного MOC во вторичном потоке.

Теперь мой код является потокобезопасным в соответствии с действиями, связанными с coredata, поэтому программа не сбой.

Еще раз спасибо сообществу.

Luis