gpt4 book ai didi

ios - 如何在运行时检查属性是否被声明为@dynamic

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:03:28 28 4
gpt4 key购买 nike

我正在研究字典的动态实现,该字典还支持使用 @dynamic 关键字(类似于 NSManagedObject)声明的属性。

我可以在运行时判断一个特定的选择器是否是用@dynamic 声明的吗?这只是设计时工具的编译器技巧并在运行时丢失,还是有某种方法可以检查它?

+ (BOOL) resolveInstanceMethod:(SEL)sel
{
NSString *method = NSStringFromSelector(sel);
// ideally I could also check here if the selector is @dynamic
if ([method hasPrefix:@"set"] && [method rangeOfString:@":"].location == method.length -1) {
class_addMethod([self class], sel, (IMP) dynamicSet, "v@:@");
return YES;
}
else if ([method hasPrefix:@"get"] && [method rangeOfString:@":"].location == method.length -1) {
class_addMethod([self class], sel, (IMP) dynamicGet, "v@:@");
return YES;
}

BOOL value = [super resolveInstanceMethod:sel];
return value;
}

此外,我的类是 NSDictionary 的子类,但是当为现有方法调用 [super resolveInstanceMethod:sel] 时它仍然返回 false?

最佳答案

如果您知道属性的名称,您可以使用一些运行时函数来调查它是否是动态属性,如以下函数所示。确保导入 <objc/runtime.h> .

BOOL isClassPropertyDynamic(Class theClass, NSString *propertyName)
{
BOOL isDynamic = NO;
objc_property_t property = class_getProperty(theClass, [propertyName UTF8String]);
char *dynamicAttributeValue = property_copyAttributeValue(property, "D");
if (dynamicAttributeValue != NULL) {
isDynamic = YES;
free(dynamicAttributeValue);
}
return isDynamic;
}

但是,从选择器名称到属性并不总是那么容易,因为 getter 和 setter 名称都可以在声明时自定义。通常,这只适用于 bool 属性的 getter,但从技术上讲,任何人都可以打破该约定。

通常,如果一个选择器以“set”开头,后跟一个大写字母并在末尾包含一个“:”,则属性名称将是删除“set”和“:”并生成第一个字母的字符串小写。如果一个选择器以“is”开头,后跟一个大写字母并且没有参数,那么与之对应的属性名称将是删除“is”并将第一个字母小写的字符串。没有参数且不以“is”和大写字母开头的选择器通常具有相同的属性名称和选择器名称。

同样,这只是约定俗成,会被某个地方的人打破。因此,您必须确定确定选择器是否对应于动态属性是否真的有值(value)(比如 borrrden 我怀疑它是否真的相关,但我不熟悉您的要求)。

您还可以按照 rob mayoff 从评论中提出的出色建议“迭代所有属性(使用 class_copyPropertyList )并检查每个属性的 G 和 S(属性)”以构建选择器和属性之间的映射。

关于ios - 如何在运行时检查属性是否被声明为@dynamic,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18179264/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com