Усеченные базовые данные NSData объекты - PullRequest
1 голос
/ 27 января 2010

Я сохраняю массивы значений типа double в объекте NSData *, который сохраняется как двоичное свойство в модели данных Core Data (SQLite). Я делаю это для хранения выборочных данных для построения графиков в приложении для iPhone. Иногда, когда в двоичном объекте более 300 двойников, не все двойники сохраняются на диск. Когда я закрываю и перезапускаю свое приложение, может сохраняться до 25 точек данных или до 300.

Использование NSSQLitePragmasOption с synchronous = FULL, и это может иметь значение. Трудно сказать, так как ошибка прерывистая.

Учитывая предупреждения о проблемах производительности в результате использования синхронного = FULL, я ищу советы и указатели.

Спасибо.

[[ Редактировать: вот код. ]]

(Пока еще не реализованное) намерение -addToCache: добавить каждый новый элемент данных в кэш, но периодически очищать (сбой?) Объект данных.

Из данных.м


@dynamic dataSet; // NSData * attribute of Data entity

 - (void) addDatum:(double_t)datum
    {
    DLog(@"-[Data addDatum:%f]", datum);
    [self addToCache:datum];
    }

- (void) addToCache:(double_t)datum
    {
    if (cache == nil)
        {
        cache = [NSMutableData dataWithData:[self dataSet]];
        [cache retain];
        }
    [cache appendBytes:&datum length:sizeof(double_t)];
    DLog(@"-[Data addToCache:%f] ... [cache length] = %d; cache = %p", datum, [cache length], cache);
    [self flushCache];
    }

- (void) wrapup
    {
    DLog(@"-[Data wrapup]");
    [self flushCache];
    [cache release];
    cache = nil;
    DLog(@"[self isFault] = %@", [self isFault] ? @"YES" : @"NO"); // [self isFault] is always NO.
    }

- (void) flushCache
    {
    DLog(@"flushing cache to store");
    [self setDataSet:cache];
    DLog(@"-[Data flushCache:] [[self dataSet] length] = %d", [[self dataSet] length]);
    }

- (double*) bytes
    {
    return (double*)[[self dataSet] bytes];
    }

- (NSInteger) count
    {
    return [[self dataSet] length]/sizeof(double);
    }

- (void) dump
    {
    ALog(@"Dump Data");
    NSInteger numDataPoints = [self count];
    double *data = (double*)[self bytes];
    ALog(@"numDataPoints = %d", numDataPoints);
    for (int i = 0; i 

1 Ответ

0 голосов
/ 01 февраля 2010

Я пытался получить поведение, как если бы моя сущность Core Data могла иметь атрибут NSMutableData. Для этого мой NSManagedObject (называемый Data) имел атрибут NSData и ивара NSMutableData. Мое приложение берет образцы данных с датчика и добавляет каждую точку данных к набору данных - вот почему мне понадобился этот дизайн.

На каждой новой точке данных был добавлен NSMutableData, а затем для атрибута NSData было установлено NSMutableData.

Я подозреваю, что из-за того, что указатель NSData не изменился (хотя его содержимое было), базовые данные не оценили количество изменений. Вызов -hasChanged для NSManagedObjectContext показал, что произошли изменения, а вызов -updatedObjects даже перечислил объект Data как измененный. Но реальные записываемые данные, похоже, были усечены (иногда).

Чтобы обойти это, я немного изменил вещи. Новые точки данных все еще добавляются к NSMutableData , но Атрибут NSData устанавливается только после завершения выборки. Это означает, что существует вероятность того, что сбой может привести к усечению данных, но, по большей части, это обходное решение, похоже, решило проблему.

Caveat emptor: ошибка всегда была прерывистой, так что, возможно, она все еще существует, но ее сложнее проявить.

...