Как я могу сделать NSObject, который создается в коде значения ключа времени выполнения, совместимым - PullRequest
0 голосов
/ 12 июня 2018

Прежде всего, я хочу отметить, что да, есть много вопросов на эту тему по переполнению стека, но ни один из них не помог.Я также пытался спросить у владельцев этих советов, но не смог связаться ни с одним из них.

Вот мой сценарий.Я получаю данные от API, который является массивом объектов.Все эти объекты имеют одинаковую структуру, но они динамически изменяются от конечной точки API.Когда я сделал NSArray из NSDictionary и попытался установить мой источник данных сетки со значением предоставленного массива.Это не сработало.Когда я посмотрел документацию IGGridViewDataSourceHelper, я обнаружил следующую информацию: «На данный момент данные должны быть производными NSObject и иметь хотя бы одно свойство».Поэтому я начал думать о способе создания NSObject во время выполнения.Мне удалось найти какой-то ресурс в документации для разработчиков Apple, чтобы сделать это.

Учитывая, что словарь переменных задан в функции

Пожалуйста, проверьте следующее

- (NSArray *)getRecrodsFromDictionary: (NSDictionary*)dictionary {
    // the following include the array that I want to turn into objects
    NSArray * response = [self parseKey:@"responseDetails" fromDictionary:dictionary];
    NSMutableArray * rows = [[NSMutableArray alloc] init];
    if ([response count] != 0) {
        // 1. get all NSDictionary keys
        NSDictionary * temp = response[0];
        NSArray * keys = [temp allKeys];

        // 2. create a class
        Class ModelClass = objc_allocateClassPair([NSObject class], "WidgetDetailsModel", 0);

        // 3. all class variables with the same name as key retrieved from NSDictionary
        for (NSString * key in keys) {
            NSString * currkey = [key capitalizedString];
            const char * name = [currkey UTF8String];
            class_addIvar(ModelClass, name, sizeof(id), rint(log2(sizeof(id))), @encode(NSString));
        }

        // 4. register a class to be used
        objc_registerClassPair(ModelClass);

        for (NSDictionary * curr in response) {
            // create object
            id MC = [[ModelClass alloc] init];
            for (NSString * key in keys) {
                // set values
                const char * name = [key cStringUsingEncoding:NSASCIIStringEncoding];
                Ivar CurrVar = class_getInstanceVariable(ModelClass, name);
                NSString * newValue = [curr objectForKey: key];
                object_setIvar(MC, CurrVar, newValue);
            }
            // add object to array
            [rows addObject:MC];
        }
    }
    return [rows copy];
} 

Как только я получаю возвращаемое значение и пытаюсь установить его в переменную данных источника данных, я получаю следующую ошибку времени выполнения:

[valueForUndefinedKey:]: этот класс не совместим с ключом значения кода для ключа AssetsClass.

Я не могу найти какой-либо информации о том, как сделать созданное во время выполнения значение ключа NSObject кодируемым.Как сделать так, чтобы значение ключа соответствовало кодированию?

Редактировать 1: Мне удалось обойти ошибку времени выполнения, сделав имена полей заглавными.Теперь таблица заполняется пустыми данными (с тем же количеством строк, что и у данных, но с пустым текстом в нем), что было правильным, потому что значения iVar не сохраняются.Как я могу сохранить его?

Редактировать 2: Я все еще не могу сохранить значение iVar, поэтому я изменил расположение функции на тот же класс UIView, который затем сохранял его в течение короткого периода времени.время, когда я должен был установить значение данных источника данных сетки.Мне любопытно узнать, есть ли способ сохранить iVar или установить один из его атрибутов как сильный / сохранить, чтобы пометить его для процесса освобождения.

1 Ответ

0 голосов
/ 25 июня 2018

После долгого поиска в Google, StackOverFlow и других форумах и исследованиях, связанных с iOS.Вот вывод, который мне удалось найти.Ивар в объективе-c всегда будет слабой ссылкой.Другими словами, нет способа (который я могу найти), который делает Ивар сильной ссылкой.Это может быть достигнуто только с помощью свойства throw с установкой атрибута каждого созданного свойства.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...