Я прилагаю все усилия, чтобы объяснить, как это работает, но это довольно запутанно и длительно. Дайте мне знать, если что-то я могу сделать, чтобы уточнить.Как применить KVO к @ динамическим свойствам, созданным во время выполнения?
Я застрял в концепциях KVC и KVO.
У меня есть класс ввода (NSObject).
Класс входа имеет частный переменный объектProperties (NSDictionary), значение которого исходит от сервера.
Предположим, что objectProperties имеет ключевую «цену», «скидку» и т. Д., Тогда я хочу создать динамические свойства в экземпляре класса Entry.
Эти ключи могут варьироваться в зависимости от ответа и динамических переменных.
Теперь, когда пользователь хочет использовать KVO по тем же свойствам, они недоступны.
Для создания динамических свойств, и это Getter/сеттер:
-(NSString*)propName:(NSString*)name {
name = [name stringByReplacingOccurrencesOfString:@":" withString:@""];
NSRange r;
r.length = name.length -1 ;
r.location = 1;
NSString* firstChar = [name stringByReplacingCharactersInRange:r withString:@""];
if([firstChar isEqualToString:[firstChar lowercaseString]])
{return name;}
r.length = 1;
r.location = 0;
NSString* theRest = [name stringByReplacingCharactersInRange:r withString:@""];
return [NSString stringWithFormat:@"%@%@", [firstChar lowercaseString] , theRest];
}
-(NSString*)setterName:(NSString*)name {
name = [self propName:name];
NSRange r;
r.length = name.length -1 ;
r.location = 1;
NSString* firstChar = [name stringByReplacingCharactersInRange:r withString:@""];
r.length = 1;
r.location = 0;
NSString* theRest = [name stringByReplacingCharactersInRange:r withString:@""];
return [NSString stringWithFormat:@"set%@%@", [firstChar uppercaseString] , theRest];
}
-(NSString*)propNameFromSetterName:(NSString*)name {
NSRange r;
r.length = 3 ;
r.location = 0;
NSString* propName = [name stringByReplacingCharactersInRange:r withString:@""];
return [self propName:propName]; }
-(NSString*)ivarName:(NSString*)name {
NSRange r;
r.length = name.length -1 ;
r.location = 1;
NSString* firstChar = [name stringByReplacingCharactersInRange:r withString:@""].lowercaseString;
if([firstChar isEqualToString:@"_"])
return name;
r.length = 1;
r.location = 0;
NSString* theRest = [name stringByReplacingCharactersInRange:r withString:@""];
return [NSString stringWithFormat:@"_%@%@",firstChar, theRest]; }
NSObject *getter(id self, SEL _cmd)
{
NSString* name = NSStringFromSelector(_cmd);
NSString* ivarName = [self ivarName:name];
Ivar ivar = class_getInstanceVariable([self class], [ivarName UTF8String]);
return object_getIvar(self, ivar);
}
void setter(id self, SEL _cmd, NSObject *newObj)
{
NSString* name = [self propNameFromSetterName:NSStringFromSelector(_cmd)];
NSString* ivarName = [self ivarName:name];
Ivar ivar = class_getInstanceVariable([self class], [ivarName UTF8String]);
id oldObj = object_getIvar(self, ivar);
if (![oldObj isEqual: newObj])
{
object_setIvar(self, ivar, newObj);
[newObj copy];
}
}
-(NSDictionary *)createProperties:(NSArray *)propNames {
NSMutableDictionary* keys = [[NSMutableDictionary alloc]init];
for(NSString* key in propNames)
{
NSString* propName = [self propName: key];
NSString* iVarName = [self ivarName:propName];
class_addIvar([self class], [iVarName UTF8String] , sizeof(NSObject*), log2(sizeof(NSObject*)), @encode(NSObject));
objc_property_attribute_t a1 = { "T", "@\"NSObject\"" };
objc_property_attribute_t a2 = { "&", "" };
objc_property_attribute_t a3 = { "N", "" };
objc_property_attribute_t a4 = { "V", [iVarName UTF8String] };
objc_property_attribute_t attrs[] = { a1, a2, a3, a4};
class_addProperty([self class], [propName UTF8String], attrs, 4);
class_addMethod([self class], NSSelectorFromString(propName), (IMP)getter, "@@:");
class_addMethod([self class], NSSelectorFromString([self setterName:propName]), (IMP)setter, "[email protected]:@");
id val = [self.objectProperties objectForKey:key];
[keys setValue:val forKey:propName];
}
return keys;
}
Но когда пользователь хочет наблюдать любые свойства, он не доступен в пользовательском классе.
Я смущен, как создавать динамические свойства и применять KVO.
Я также попытался сделать подкласс класса Entry ie (myEntry, который пользователь создает в конце) и определить все переменные там. но как мне установить его значение там? Поскольку я хочу, чтобы это свойство было прочитано только.
Что вы в конечном итоге пытаетесь достичь? Есть, вероятно, более простые способы сделать это. Создание динамических свойств и методов во время выполнения не очень распространено. – jtbandes
Пожалуйста, объясните, чего вы действительно хотите достичь? Может быть, краткое описание - это то, что мне нужно. –
в основном у меня есть класс ввода с objectProperties как частная переменная NSDictionary. Я хочу сделать ключи внутри этого словаря в качестве свойств во время выполнения, поэтому, когда пользователь хочет наблюдать за изменениями в стоимости этого имущества, он будет уведомлен. Эти ключевые свойства объекта варьируются в зависимости от ответа JSON. Иногда ключи - это цена, скидка, описание продукта. И в другой раз они являются именем категории, описанием категории и т. Д. Для этого я хочу создать динамические свойства. –