Усеченные основные данные Объекты NSData

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

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

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

Спасибо.

[[Изменить: вот код]]

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

Из Data.m


@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 

person westsider    schedule 27.01.2010    source источник
comment
Вау, если это действительно ошибка во фреймворке, а не в вашем коде, я надеюсь, что вы подадите жалобу в Apple, потому что это очень-очень плохо.   -  person Hunter    schedule 27.01.2010
comment
Рассматривали ли вы создание правильных сущностей и отношений для вашей модели данных вместо того, чтобы пытаться сохранить массив в одном атрибуте?   -  person gerry3    schedule 27.01.2010
comment
Вы подтвердили, что данные правильно конвертируются в двоичную форму? Я бы сказал, что ошибка, скорее всего, связана с кодом преобразования, который, как указал St3fan, нам необходимо увидеть. Попробуйте перед сохранением преобразовать его обратно из двоичного кода в двойные и выполнить проверку утверждения. Это позволит отловить ошибку, если она действительно присутствует в коде преобразования.   -  person Marcus S. Zarra    schedule 27.01.2010
comment
gerry3 - не понимаю, что вы имеете в виду. У меня есть сущности «Эксперимент», которые имеют отношения «один-ко-многим» с сущностями «Выполнить» (для сдерживания), а сущности «Выполнить» имеют отношения «один-к-одному» с сущностями «Данные» (хотя большинство атрибутов выполнения хранятся в Запустить объект). Объект данных - это образец данных из измерения, который может содержать десятки тысяч точек данных. Если есть лучший способ представить это, чем BLOB, я все уши.   -  person westsider    schedule 28.01.2010
comment
St3fan - я добавил часть кода для объекта данных (который является NSManagedObject). Во время выборки данных из измерения (например, датчика температуры) - [Data addDatum:] вызывается для каждой точки данных. Когда выборка завершена, вызывается - [Data wrapup]. Вызывающий также вызывает -save в NSManagedObjectContext. Иногда - например, когда во время выполнения приложения выполняется выборка из нескольких прогонов или когда уже есть несколько сохраненных прогонов - новый прогон и его атрибут NSData данных сохраняются должным образом. Но первый запуск эксперимента часто урезается.   -  person westsider    schedule 28.01.2010
comment
Маркус - Спасибо. Моя последняя гипотеза заключается в том, что объект Data не поврежден (что, как я понимаю, означает отличие от сохраненной версии). Я попытался вызвать ошибку (добавив атрибут BOOL, который я переключил), но это не привело к ошибке объекта. Что касается кода преобразования, у меня есть метод -dump (в отредактированном вопросе). Я думаю, что это преобразование, которое вы предложили. Он показывает полные NSData после создания - даже если при последующем запуске приложения отображается усечение. В любом случае, я не уверен, почему сохранение NSData объекта данных иногда работает, а другие нет.   -  person westsider    schedule 28.01.2010


Ответы (1)


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

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

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

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

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

person westsider    schedule 01.02.2010