Is there a method that returns all the keys for an object conforming to the NSKeyValueCoding protocol?
是否有方法返回符合NSKeyValueCoding协议的对象的所有键?
Something along the lines of [object getPropertyKeys]
that would return an NSArray of NSString objects. It would work for any KVC-compliant object. Does such a method exist? I haven't found anything in searching the Apple docs so far.
沿着[object getPropertyKeys]行返回NSString对象的NSArray。它适用于任何kvc兼容的对象。这种方法存在吗?到目前为止,我还没有在苹果文档中找到任何东西。
Thanks, G.
谢谢,G。
6 个解决方案
#1
33
#import "objc/runtime.h"
unsigned int outCount, i;
objc_property_t *properties = class_copyPropertyList([self class], &outCount);
for(i = 0; i < outCount; i++) {
objc_property_t property = properties[i];
const char *propName = property_getName(property);
if(propName) {
const char *propType = getPropertyType(property);
NSString *propertyName = [NSString stringWithUTF8String:propName];
NSString *propertyType = [NSString stringWithUTF8String:propType];
}
}
free(properties);
#2
3
Use class_getPropertyList. That will tell you all the @properties
of the object.
使用class_getPropertyList。这将告诉您对象的所有@properties。
It won't necessarily list every KVC-compliant property, because any method that takes no arguments and returns a value is a valid KVC-compliant getter. There's no 100%-reliable way for the runtime to know which ones behave as properties (e.g., -[NSString length]
) and which ones behave as commands (e.g., -[NSFileHandle readDataToEndOfFile]
).
它不一定列出所有kvc兼容的属性,因为任何不接受参数并返回值的方法都是有效的kvc兼容的getter。运行时没有100%可靠的方法知道哪些属性(例如-[NSString length])和哪些属性作为命令(例如-[NSFileHandle readDataToEndOfFile])。
You should be declaring your KVC-compliant properties as @properties
anyway, so this shouldn't be too big of a problem.
无论如何,您应该将kvc兼容的属性声明为@properties,因此这应该不是什么大问题。
#3
1
There is no such method as the KVO system does not require objects/classes to register with it which properties they support KVO for. Any key could potentially support KVO, the only way to know is from the author's documentation.
没有这样的方法,例如KVO系统不需要对象/类向它注册它们支持KVO的属性。任何键都可能支持KVO,唯一的方法就是从作者的文档中知道。
And of course, there is no guarantee that an @property
will support KVO; it's quite possible to write a property that doesn't (and may be necessary sometimes). So, getting a list of a class's @property
s and then assuming they're KVO-compliant would be a dangerous choice in my opinion.
当然,@property不能保证支持KVO;编写一个不需要的属性是很有可能的(有时可能是必需的)。因此,在我看来,得到一个类的@propertys列表,然后假设它们与kvos兼容是一个危险的选择。
#4
0
You need a getPropertyType function. See this post: Get an object attributes list in Objective-C
您需要一个getPropertyType函数。请参阅本文:获取Objective-C中的对象属性列表
#5
0
For Swift onlookers, you can get this functionality by utilising the Encodable
functionality. I will explain how:
对于快速的旁观者,你可以通过使用可编码的功能来获得这个功能。我将解释如何:
-
Conform your object to
Encodable
protocol使您的对象符合可编码协议
class ExampleObj: NSObject, Encodable { var prop1: String = "" var prop2: String = "" }
-
Create extension for
Encodable
to providetoDictionary
functionality为Encodable创建扩展以提供字典功能
public func toDictionary() -> [String: AnyObject]? { let encoder = JSONEncoder() encoder.outputFormatting = .prettyPrinted guard let data = try? encoder.encode(self), let json = try? JSONSerialization.jsonObject(with: data, options: .init(rawValue: 0)), let jsonDict = json as? [String: AnyObject] else { return nil } return jsonDict }
-
Call
toDictionary
on your object instance and accesskeys
property.在对象实例和访问键属性上调用toDictionary。
let exampleObj = ExampleObj() exampleObj.toDictionary()?.keys
-
Voila! Access your properties like so:
瞧!访问您的属性如下:
for k in exampleObj!.keys { print(k) } // Prints "prop1" // Prints "prop2"
#6
-1
Environment:Xcode7.2,iOS9.2
环境:Xcode7.2 iOS9.2
I use code snippet below to get property names of a specified class,it works fine:
我使用下面的代码片段获取指定类的属性名,它工作得很好:
import "objc/runtime.h"
unsigned int outCount, i;
objc_property_t *properties = class_copyPropertyList([SNBankBean class], &outCount);
for(i = 0; i < outCount; i++) {
objc_property_t property = properties[i];
const char *propName = property_getName(property);
if(propName) {
NSString *propertyName = [NSString stringWithUTF8String:propName];
NSLog(@"the property name is %@",propertyName);
if ([propertyName isEqualToString:bank_name]) {
self.isBankExisted=YES;
}
}
}
free(properties);
#1
33
#import "objc/runtime.h"
unsigned int outCount, i;
objc_property_t *properties = class_copyPropertyList([self class], &outCount);
for(i = 0; i < outCount; i++) {
objc_property_t property = properties[i];
const char *propName = property_getName(property);
if(propName) {
const char *propType = getPropertyType(property);
NSString *propertyName = [NSString stringWithUTF8String:propName];
NSString *propertyType = [NSString stringWithUTF8String:propType];
}
}
free(properties);
#2
3
Use class_getPropertyList. That will tell you all the @properties
of the object.
使用class_getPropertyList。这将告诉您对象的所有@properties。
It won't necessarily list every KVC-compliant property, because any method that takes no arguments and returns a value is a valid KVC-compliant getter. There's no 100%-reliable way for the runtime to know which ones behave as properties (e.g., -[NSString length]
) and which ones behave as commands (e.g., -[NSFileHandle readDataToEndOfFile]
).
它不一定列出所有kvc兼容的属性,因为任何不接受参数并返回值的方法都是有效的kvc兼容的getter。运行时没有100%可靠的方法知道哪些属性(例如-[NSString length])和哪些属性作为命令(例如-[NSFileHandle readDataToEndOfFile])。
You should be declaring your KVC-compliant properties as @properties
anyway, so this shouldn't be too big of a problem.
无论如何,您应该将kvc兼容的属性声明为@properties,因此这应该不是什么大问题。
#3
1
There is no such method as the KVO system does not require objects/classes to register with it which properties they support KVO for. Any key could potentially support KVO, the only way to know is from the author's documentation.
没有这样的方法,例如KVO系统不需要对象/类向它注册它们支持KVO的属性。任何键都可能支持KVO,唯一的方法就是从作者的文档中知道。
And of course, there is no guarantee that an @property
will support KVO; it's quite possible to write a property that doesn't (and may be necessary sometimes). So, getting a list of a class's @property
s and then assuming they're KVO-compliant would be a dangerous choice in my opinion.
当然,@property不能保证支持KVO;编写一个不需要的属性是很有可能的(有时可能是必需的)。因此,在我看来,得到一个类的@propertys列表,然后假设它们与kvos兼容是一个危险的选择。
#4
0
You need a getPropertyType function. See this post: Get an object attributes list in Objective-C
您需要一个getPropertyType函数。请参阅本文:获取Objective-C中的对象属性列表
#5
0
For Swift onlookers, you can get this functionality by utilising the Encodable
functionality. I will explain how:
对于快速的旁观者,你可以通过使用可编码的功能来获得这个功能。我将解释如何:
-
Conform your object to
Encodable
protocol使您的对象符合可编码协议
class ExampleObj: NSObject, Encodable { var prop1: String = "" var prop2: String = "" }
-
Create extension for
Encodable
to providetoDictionary
functionality为Encodable创建扩展以提供字典功能
public func toDictionary() -> [String: AnyObject]? { let encoder = JSONEncoder() encoder.outputFormatting = .prettyPrinted guard let data = try? encoder.encode(self), let json = try? JSONSerialization.jsonObject(with: data, options: .init(rawValue: 0)), let jsonDict = json as? [String: AnyObject] else { return nil } return jsonDict }
-
Call
toDictionary
on your object instance and accesskeys
property.在对象实例和访问键属性上调用toDictionary。
let exampleObj = ExampleObj() exampleObj.toDictionary()?.keys
-
Voila! Access your properties like so:
瞧!访问您的属性如下:
for k in exampleObj!.keys { print(k) } // Prints "prop1" // Prints "prop2"
#6
-1
Environment:Xcode7.2,iOS9.2
环境:Xcode7.2 iOS9.2
I use code snippet below to get property names of a specified class,it works fine:
我使用下面的代码片段获取指定类的属性名,它工作得很好:
import "objc/runtime.h"
unsigned int outCount, i;
objc_property_t *properties = class_copyPropertyList([SNBankBean class], &outCount);
for(i = 0; i < outCount; i++) {
objc_property_t property = properties[i];
const char *propName = property_getName(property);
if(propName) {
NSString *propertyName = [NSString stringWithUTF8String:propName];
NSLog(@"the property name is %@",propertyName);
if ([propertyName isEqualToString:bank_name]) {
self.isBankExisted=YES;
}
}
}
free(properties);