Coredata & NSPersistentDocument: сбой суммы номеров столбцов

У меня проблема с привязкой столбца @sum в моей программе:

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

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

Проблема, которая у меня есть: я создал метку, которую привязываю к @sum столбца со свойством NSNumber. Вот как я это сделал

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

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

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

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

Вторая проблема та же, но воспроизводится под другим углом. Вместо того, чтобы использовать "выделение", я попытался использовать "упорядоченные объекты". В этом случае проблема возникает даже при импорте из 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 Collection

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

Мое первоначальное предположение, что это связано с невозможностью доступа к содержимому контроллера объекта после загрузки пера, однако я выполнил рекомендацию выполнить первый Fetch, как этот, но безуспешно:

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

Продолжая эту идею, я обнаружил, что если я создаю "настоящий" полный 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 @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 ответ

Решение

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

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

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

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

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

Луис

Другие вопросы по тегам