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, поэтому программа не падает.
Еще раз спасибо сообществу.
Луис