Цель C - откликается на динамические свойства - PullRequest
4 голосов
/ 25 января 2012

В настоящее время я сталкиваюсь с проблемой проверки, существует ли свойство объекта (NSManagedObject) или нет.

К сожалению, метод

[[MyObject class] respondsToSelector:@selector(myProperty)];

всегда возвращает NO.

Я думаю, это потому, что свойство, сгенерированное CoreData, является новым свойством стиля ala

@property (nonatomic, strong) NSString *myProperty

Итак, есть идеи, как решить эту проблему?из ваших предложений;)

Заранее спасибо!Alex

Ответы [ 3 ]

15 голосов
/ 25 января 2012

[[MyObject class] respondsToSelector:...] спрашивает, реагирует ли метаобъект на этот селектор. Таким образом, он спрашивает, существует ли метод класса с этим селектором. Ваш код вернет YES, если у вас есть:

+ (NSString *)myProperty;

Возвращает NO, потому что у вас есть эквивалент метода экземпляра:

- (NSString *)myProperty;

Вам нужно позвонить respondsToSelector: на экземпляр вашего класса.

Обычно вы можете использовать instancesRespondToSelector: непосредственно в метаклассе (так, [MyObject instancesRespondToSelector:...]), но Core Data синтезирует соответствующие реализации методов только при создании объекта, так что это не стартер. Однако вы можете создать экземпляр по обычному маршруту NSEntityDescription и проверить на нем respondsToSelector:.

Поскольку это все базовые данные, альтернативой может быть запрос NSManagedObjectModel соответствующего NSEntityDescription через его словарь entitiesByName и проверка propertiesByName словаря описания сущности.

1 голос
/ 19 июля 2015

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

NSArray * keys = [myObject allKeys];
for(NSString * key in keys)
{
    NSString * string = [NSString stringWithFormat:@"set%@:", [key capitalizedString]];
    SEL selector = NSSelectorFromString(string);
    if([myObject respondsToSelector:selector] == YES)
    {
        id object = [dict objectForKey:key];

        // To massage the compiler's warnings avoid performSelector
        IMP imp = [card methodForSelector:selector];
        void (*method)(id, SEL, id) = (void *)imp;
        method(myObject, selector, object);
    }
}

Этот код удовлетворяет потребности, когда вы, возможно, не перевариваете все данные, которые вы получаете в словаре. В данном случае это был разреженный json, поэтому некоторые данные не всегда могут существовать в json, поэтому переход через атрибуты myObjects в поисках соответствующего ключа будет просто напрасной тратой.

0 голосов
/ 25 января 2012

Вы синтезируете свойство в файле класса?

@interface SomeClass : NSObject
{
    @property (nonatomic, strong) NSString *myProperty
}
@end


@implementation SomeClass

    @synthesize myProperty;

@end
...