Доступ к массивам C (int [], float [] и т. Д.) С использованием среды выполнения Objective C - PullRequest
0 голосов
/ 16 декабря 2011

Я пытаюсь сохранить все переменные в моем классе в NSUserDefaults, используя objc / runtime. И ниже код, который я использую.

NSUInteger count;
Ivar *iVars = class_copyIvarList([self class], &count);
for (NSUInteger i=0; i<count; i++) 
{
    Ivar var    = iVars[i];
    NSString *varName = [NSString stringWithCString:ivar_getName(var) encoding:NSUTF8StringEncoding];
    NSString *varType = [NSString stringWithCString:ivar_getTypeEncoding(var) encoding:NSUTF8StringEncoding];

    if([varType hasPrefix:@"["])
    {
        NSLog(@"Array");
        id var1 = [_manager valueForKey:varName];

        NSLog(@"--- %@", var1);

        NSData *data = [NSData dataWithBytes:&([_manager valueForKey:varName]) length:sizeof([_manager valueForKey:varName])]
        [[NSUserDefaults standardUserDefaults] setObject:[_manager valueForKey:varName] forKey:varName];
    }
    else
    {
        NSLog(@"NonArray");
        NSLog(@"---  %@", [_manager valueForKey:varName]);
        [[NSUserDefaults standardUserDefaults] setObject:[_manager valueForKey:varName] forKey:varName];
    }

}

free(iVars);

Проблема в том, что, когда есть только примитивные типы данных, приведенный выше код работает просто отлично. Но когда я пытаюсь получить доступ к переменной массива, такой как int[] или float[], происходит сбой при SIGABRT. он не показывает никаких других сообщений.

valueForKey не возвращает значений для массивов C.

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

Заранее спасибо,

Suran

1 Ответ

2 голосов
/ 16 декабря 2011

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

Если бы я действительно хотел сделать то, что вы делаете, я бы заставил сам класс создать массив, предоставив NSData. Если это распространено, вы можете использовать соглашение:

 - (int*)pixelBuffer;
 - (NSData *)pixelBufferForSerialization; // << returns a deep copy of
                                          //    self.pixelBuffer as an
                                          //    NSData instance.

Таким образом, приведенная выше реализация увидит, что свойство определяет скалярный массив, а затем запросит NSData * data = obj.pixelBufferForSerialization; вместо попытки создания самих данных.

Обновление

Лучше позволить классу сделать это. Вот как создать NSData, используя такой массив:

@interface DataManager : NSObject
{
@private
    int* things;
    size_t nThings;
}

- (int*)things;
- (NSData *)thingsAsNSData;

@end

@implementation DataManager

- (int*)things
{
    return things;
}

- (NSData *)thingsAsNSData
{
    // note: you may need to choose an endianness for serialization
    if (0 == nThings) return [NSData data];w
    return [NSData dataWithBytes:things length:nThings * sizeof(things[0])];
}

@end

Опять же - вы хотите, чтобы класс создавал данные, потому что он лучше знает свою собственную структуру.

...