如何使用@encode()获取@“NSArray” 在 Objective-C 中
我正在使用运行时函数来获取属性的类型(感谢 eJames 帮助我找出这种方法)。 属性的属性字符串如下所示:
T@"NSArray",&,Vstuff
我需要检查属性类型是否是数组,目前我正在这样做:
- (BOOL)valueForKeyIsArray:(NSString *)key fromTagret:(id)target
{
NSString *lowerCaseKey = [self convertToKVCKey:key];
objc_property_t property = class_getProperty([target class], [lowerCaseKey UTF8String]);
NSString *propertyAttrs = [NSString stringWithUTF8String:property_getAttributes(property)];
NSString *encodedType = @"@\"NSArray\"";
NSRange range = [propertyAttrs rangeOfString:encodedType options:NSLiteralSearch];
return range.location != NSNotFound;
}
但是由于Apple可以随时更改类型定义字符串,我想生成这个@“NSArray”类型的字符串。 我用@encode()尝试过,但是没有用:
NSString *encodedType = [NSString stringWithUTF8String:@encode(NSArray *)];
那么如何生成这种类型的字符串呢? 或者是否有更好的方法来检查此属性属性是否包含数组类型?
I'm using the runtime functions to get the type of a property (thanks to eJames for helping me to figure out this way).
The attribute string of the property looks like this:
T@"NSArray",&,Vstuff
I need to check if the property type is an array, at the moment I'm doing it like this:
- (BOOL)valueForKeyIsArray:(NSString *)key fromTagret:(id)target
{
NSString *lowerCaseKey = [self convertToKVCKey:key];
objc_property_t property = class_getProperty([target class], [lowerCaseKey UTF8String]);
NSString *propertyAttrs = [NSString stringWithUTF8String:property_getAttributes(property)];
NSString *encodedType = @"@\"NSArray\"";
NSRange range = [propertyAttrs rangeOfString:encodedType options:NSLiteralSearch];
return range.location != NSNotFound;
}
But since Apple can change the type definition string at any time, I would like to generate this @"NSArray" type string. I tried it with @encode(), but it did not work:
NSString *encodedType = [NSString stringWithUTF8String:@encode(NSArray *)];
So how can I generate this type string? Or is there a better way to check if this property attributes contain the array type?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
没有办法检查这一点。 在 Objective-C 源代码中,类型为 NSArray * 的变量仅用于编译器发出警告。 它没有任何意义,并且在运行时不存在。 如果您将
NSArray
错误地输入为NSString
,编译时您会收到很多警告,但您的代码在运行时的行为完全相同。 在运行时,我们知道 ivar/property 是“一个对象”。另一种思考方式是,一旦 Objective-C 被编译,所有对象引用都是 id 引用。
There is no way to check this. In Objective-C source code the variables being typed as
NSArray *
is only there for the compiler to issue warnings. It has no meaning, and does not exist at runtime. If you mis-typed anNSArray
as anNSString
, you would get lots of warnings when compiling, but your code would behave exactly the same when run. At runtime all that is known is that the ivar/property is "an object".Another way to think of it, is that once Objective-C is compiled, all object references are
id
references.只要接受这样一个事实:如果运行时发生变化,您的代码将会崩溃,然后继续前进。 但是,我认为您可能对
NSMutableArray *
、CFArrayRef
或CFMutableArrayRef
类型的 ivars 进行了错误分类。 您似乎还假设所有键都直接对应于声明的属性。最干净的解决方案可能是断言用于测试的示例对象(目标)必须具有该键的非零值,并且只需获取该值并测试
[[target valueForKey:key] isKindOfClass :[NSArray 类]]
。Just accept that if the runtime changes, your code will break, and move on. However, I think you might be miscategorizing ivars of type
NSMutableArray *
,CFArrayRef
, orCFMutableArrayRef
. You also seem to be assuming all keys correspond directly to a declared property.The cleanest solution might be to assert that the sample object being used for the test (the target) must have a non-nil value for that key, and just grab the value and test that
[[target valueForKey:key] isKindOfClass:[NSArray class]]
.