如何找到符合 KVC 的 Objective-C 对象的所有属性键?

发布于 2024-07-18 00:28:50 字数 212 浏览 9 评论 0原文

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

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

谢谢, G。

Is there a method that returns all the keys for an object conforming to the NSKeyValueCoding protocol?

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.

Thanks,
G.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

你的背包 2024-07-25 00:28:50
#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);
#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);
末骤雨初歇 2024-07-25 00:28:50

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

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

无论如何,您应该将符合 KVC 的属性声明为 @properties,因此这应该不是什么大问题。

Use class_getPropertyList. That will tell you all the @properties of the object.

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]).

You should be declaring your KVC-compliant properties as @properties anyway, so this shouldn't be too big of a problem.

野の 2024-07-25 00:28:50

不存在这样的方法,因为 KVO 系统不需要对象/类向其注册它们支持 KVO 的属性。 任何密钥都可能支持 KVO,唯一了解的方法是通过作者的文档。

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

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.

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 @propertys and then assuming they're KVO-compliant would be a dangerous choice in my opinion.

诗笺 2024-07-25 00:28:50

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

You need a getPropertyType function. See this post: Get an object attributes list in Objective-C

或十年 2024-07-25 00:28:50

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

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

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

     public func toDictionary() ->;   [字符串:任何对象]?   { 
          让编码器 = JSONEncoder() 
          编码器.outputFormatting = .prettyPrinted 
          保护让数据=尝试?   编码器.编码(自身), 
                让 json = 尝试一下?   JSONSerialization.jsonObject(with: data, options: .init(rawValue: 0)), 让 jsonDict = json as?   [字符串:AnyObject] else { 
              返回零 
          } 
          返回 jsonDict 
      } 
      
  3. 在对象实例上调用 toDictionary 并访问 keys 属性。

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

    for k in exampleObj!.keys { 
          打印(k) 
      } 
      // 打印“prop1” 
      // 打印“prop2” 
      

For Swift onlookers, you can get this functionality by utilising the Encodable functionality. I will explain how:

  1. Conform your object to Encodable protocol

    class ExampleObj: NSObject, Encodable {
        var prop1: String = ""
        var prop2: String = ""
    }
    
  2. Create extension for Encodable to provide toDictionary functionality

     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. Call toDictionary on your object instance and access keys property.

    let exampleObj = ExampleObj()
    exampleObj.toDictionary()?.keys
    
  4. Voila! Access your properties like so:

    for k in exampleObj!.keys {
        print(k)
    }
    // Prints "prop1"
    // Prints "prop2"
    
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文