26

是否有一种方法可以返回符合 NSKeyValueCoding 协议的对象的所有键?

类似的东西[object getPropertyKeys]会返回一个 NSString 对象的 NSArray。它适用于任何符合 KVC 的对象。这样的方法存在吗?到目前为止,我在搜索 Apple 文档时还没有找到任何东西。

谢谢,G。

4

5 回答 5

39
#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);
于 2009-04-23T09:22:33.333 回答
3

使用class_getPropertyList。这将告诉你所有@properties的对象。

它不一定会列出所有符合 KVC 的属性,因为任何不带参数并返回值的方法都是有效的符合 KVC 的 getter。运行时没有 100% 可靠的方法可以知道哪些行为表现为属性(例如,-[NSString length]),哪些行为表现为命令(例如,-[NSFileHandle readDataToEndOfFile])。

无论如何,您都应该声明符合 KVC 的属性@properties,所以这应该不是太大的问题。

于 2009-04-23T09:23:37.717 回答
1

没有这样的方法,因为 KVO 系统不需要对象/类向其注册它们支持 KVO 的属性。任何密钥都可能支持 KVO,唯一知道的方法是从作者的文档中。

当然,也不能保证 an@property会支持 KVO。很可能编写一个不需要的属性(有时可能是必要的)。因此,在我看来,获取一个类的列表@property然后假设它们符合 KVO 标准将是一个危险的选择。

于 2009-04-24T12:40:32.357 回答
0

您需要一个 getPropertyType 函数。请参阅这篇文章:在 Objective-C 中获取对象属性列表

于 2010-10-24T13:13:04.263 回答
0

对于 Swift 围观者,您可以通过使用该功能来获得此Encodable功能。我将解释如何:

  1. 使您的对象符合Encodable协议

    class ExampleObj: NSObject, Encodable {
        var prop1: String = ""
        var prop2: String = ""
    }
    
  2. 创建扩展Encodable以提供toDictionary功能

     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
    }
    
  3. 调用toDictionary您的对象实例并访问keys属性。

    let exampleObj = ExampleObj()
    exampleObj.toDictionary()?.keys
    
  4. 瞧!像这样访问您的属性:

    for k in exampleObj!.keys {
        print(k)
    }
    // Prints "prop1"
    // Prints "prop2"
    
于 2018-05-21T13:49:56.787 回答