如何根据 NSString 类型键测试属性是否存在和类型?

2024-02-28

在我寻求更新 iOS 项目中的核心数据模型时,我在服务器上查询 JSON 对象,这些对象在某种程度上与我的模型的托管实体相对应。我追求的最终结果是从 JSON 输出获得可靠的更新解决方案。

对于这个问题中的示例,我将命名核心数据管理对象existingObj以及传入的 JSON 反序列化字典updateDict。棘手的部分是处理这些事实:

  1. 并非所有属性existingObj存在于updateDict
  2. 并非所有属性updateDict可以在extistingObj.
  3. 并非所有类型existingObj的属性与 JSON 反序列化属性匹配。 (某些字符串可能需要自定义 Objective-C 包装器)。
  4. updateDict可能包含未初始化的键的值(nil) in existingObj.

这意味着在迭代更新的字典时,必须来回进行一些属性测试。首先我必须测试该属性是否updateDict存在于existingObj,然后我使用 KVC 设置该值,如下所示:

// key is an NSString, e.g. @"displayName"
if ([existingObj respondsToSelector:NSSelectorFromString(key)) {
    [existingObj setValue:[updateDict objectForKey:key] forKey:key];
}

虽然这部分有效,但我不喜欢我实际上正在测试的事实displayName作为吸气剂,当我正要打电话时setDisplayName:setter(间接通过 KVC)。我宁愿是类似 [existingObj hasWritablePropertyWithName:key] 的东西,但我找不到这样做的东西。

这就产生了子问题 A:如果只有属性的名称,如何测试属性设置器?

下一部分是我想根据属性的类型自动识别属性。如果两者都updateDictexistingObj有一个 NSString 作为键 @"displayName",设置新值很容易。然而,如果updateDict包含一个 NSString 键@“color”,即@“niceShadeOfGreen”,我想将其转换为正确的 UIColor 实例。但是我如何测试接收属性的类型existingObj所以我知道何时转换值以及何时简单分配?我希望得到类似于 typeOfSelector: 的东西

if ([existingObj typeOfSelector:sel] == [[updateDict objectForKey:key] class]) {
     // regular assignment
} else {
     // perform custom assignment
}

当然,这是假代码。我不能依赖测试的类型existingObj- 属性的值,因为它可能是单位化的或nil.

子问题 B:如果只有属性的名称,如何测试属性的类型?

我想就是这样。我想这一定是这里已经存在的东西的骗局,但我找不到它。也许你们可以吗?
干杯,EP。

附:如果您有更好的方法将自定义 Objective-C 对象同步到反序列化 JSON 对象,请分享!最后,结果才是最重要的。


如果你想查询一个对象是否有给定 KVC key 的 setter,称为key它对应于一个声明的属性,你需要检查它是否响应一个名为的选择器方法setKey:(以。。开始set, 将第一个字符大写key,添加尾随冒号)。例如,

NSString *key = @"displayName";
NSString *setterStr = [NSString stringWithFormat:@"set%@%@:",
                       [[key substringToIndex:1] capitalizedString],
                      [key substringFromIndex:1]];

if ([obj respondsToSelector:NSSelectorFromString(setterStr)]) {
    NSLog(@"found the setter!");
    [obj setValue:someValue forKey:key];
}

两点备注:

  • 尽管属性的 setter 名称可能不遵循上述模式,但它们不符合 KVC,因此可以安全地检查set<Key>:因为你使用 KVC 来设置相应的值。

  • KVC 不仅仅使用 setter 方法。如果没有找到 setter 方法,它会检查该类是否允许直接访问实例变量,如果是,则使用实例变量来设置值。此外,如果没有找到 setter 方法或实例变量,它会发送-setValue:forUndefinedKey:到接收者,其类可能已经覆盖了引发异常的标准实现。这在键值编码编程指南 http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/KeyValueCoding/Concepts/SearchImplementation.html%23//apple_ref/doc/uid/20000955-CJBBBFFA也就是说,如果您总是使用属性,那么检查 setter 方法应该是安全的。

至于你的第二个问题,不可能查询运行时来了解属性的实际 Objective-C 类。从运行时的角度来看,有一个特定于实现的类型编码特性 http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtPropertyIntrospection.html%23//apple_ref/doc/uid/TP40008048-CH101-SW6 and 一般类型 http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtTypeEncodings.html%23//apple_ref/doc/uid/TP40008048-CH100-SW1(例如方法参数/返回类型)。这种类型的编码使用单一编码(即@) 对于任何 Objective-C 对象,因此类型编码NSStringproperty 与 a 的类型编码相同UIColor属性,因为它们都是 Objective-C 类。

如果您确实需要此功能,一种替代方法是处理您的类并添加一个类方法,该方法返回一个字典,其中包含该类和超类中声明的每个属性(或您感兴趣的属性)的键和相应类型,或者也许某种描述语言。您必须自己执行此操作并依赖运行时不可用的信息。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何根据 NSString 类型键测试属性是否存在和类型? 的相关文章

随机推荐

  • 如何组织大型 Node.js 项目

    组织大型 Node js 项目有哪些好方法 例如 一个同时使用express js 和socket io 的应用程序 这将包括应用程序逻辑结构和文件系统 目前 我发现自己将大量代码放入一个主 js 文件中 并将代码放入一个巨大的全局对象中
  • Rails 3.1 强制使用 .html 而不是无扩展名

    我的一位客户希望他的新 Rails 应用程序看起来更像他的传统网站 他想知道我是否可以强制 url 具有文件扩展名 最好是 html 我不想对扩展进行硬编码routes rb as match controller action id ht
  • 难以通过网络蓝牙连接热敏打印机

    现在我正在开发能够连接热敏打印机的网络 我正在使用 Angular 框架 并且我使用库成功将热敏打印机与 USB 连接ng thermal printer 但我希望我的网络也能够通过网络蓝牙 BLE 蓝牙低功耗 连接热敏打印机 据我所知 B
  • 转换为乔姆斯基范式

    我确实需要你的帮助 我有这些作品 1 A gt aAb 2 A gt bAa 3 A gt 我应该应用乔姆斯基范式 CNF 为了应用上述规则 我应该 消除 产生式 消除单一生产 删除无用的符号 我立即陷入困境 原因是 A 是一个可为空的符号
  • 它仍然适用于在 RedHat7 上使用 pexpect 还是有替代方法来执行命令并响应提示?

    我尝试在 Redhat7 中使用 pexpect for ansible 但无法安装它 我只得到 pexpect noarch 2 3 11 el7 RHEL7 版本 或者 pexpect 是否有替代方法来执行命令并响应提示 看起来像的版本
  • 给定python代码的打印语句语法错误的原因是什么[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 编辑问题以包括期望的行为 特定问题或错误以及重现问题所需的最短代码 help minimal reproducible example 这
  • 将 Meteor 部署到 Android 设备时找不到构建工具修订版 24.0.1

    我错误地完全删除了 Android SDK 文件夹 之前我已经使用cordova phonegap多次将meteor部署到android设备上 当通过 Android Studio 重新安装 SDK 并尝试在设备中运行 Meteor 时 我
  • SQLAlchemy over MySQLdb 的目的

    为什么人们使用 SQLAlchemy 而不是 MySQLdb 它有什么优点 您不使用 SQLAlchemy 来代替 MySQLdb 您使用 SQLAlchemy 来访问 MySQLdb oursql 我听说更好并且性能更好的另一个 MySQ
  • Xcode 未反映来自 React-Native 的最新应用程序代码

    EDIT 好吧 事实证明这不是 AppStore 的问题 我从 Xcode 发布模式运行了应用程序 并且在模拟器上运行了相同的旧版本 我不知道为什么 但 Xcode 没有运行最新的 jsbundle 现在我发现this https stac
  • 在 Dart 中获取与正则表达式匹配的所有子字符串的最佳方法

    我想获取与字符串中的正则表达式匹配的子字符串列表 做这个的最好方式是什么 dart core 中的 RegExp 对象有Iterable
  • 用java下载包含资源(如图像)的完整网页

    有没有办法下载 html 网页及其所有资源 例如 图像 CSS 我知道如何使用 html 解析器通过遍历所有相关标签来做到这一点 但是没有easy way That is最简单的方法 困难的方法是编写自己的网络库 html 解析器等
  • SwiftUI 中 ObservedObject 和 StateObject 有什么区别

    如果我有一个ObservableObject在 SwiftUI 中我可以将其称为 ObservedObject class ViewModel ObservableObject Published var someText Hello Wo
  • 如何轻松分析 Oracle 包的执行是否存在性能问题?

    我在 11g R2 DB 中有一个 pl sql 包 它有相当多的相关过程和函数 我执行一个顶级函数 它做了很多事情 当前每秒处理 对于 Oracle 的 PL SQL 分层分析器 DBMS HPROF 来说 这似乎是一项不错的工作 作为一
  • 优化 iPhone OpenGL ES 填充率

    我的 iPhone 上有一个 Open GL ES 游戏 我的帧率很糟糕 20fps 在 iPhone 3G 上使用 Xcode OpenGL ES 性能工具 它显示 渲染器利用率 95 至 99 瓷砖利用率 27 我正在绘制很多非常大的图
  • 随机迭代所有排列

    我导入了一个大数组 我想随机迭代所有行排列 该代码被设计为在某个数组产生所需的解决方案时中断 到目前为止的尝试涉及正常的迭代扰动过程 import numpy as np import itertools file np loadtxt m
  • 单击按钮后程序停止响应

    我正在尝试制作我的第一个程序 一个端口扫描器 显示远程服务器上的所有开放端口 我已经让它在 CLI 中工作 感谢互联网 但决定制作一个 GUI Qt5 它 我希望textbox2在输入IP地址并单击 扫描 后输出所有打开的端口 并且显然程序
  • User.Identity.IsAuthenticated 与 WebSecurity.IsAuthenticated

    在 MVC4 应用程序中 在控制器逻辑中 我想检查用户是否已登录 我应该使用 User Identity IsAuthenticated Or WebSecurity IsAuthenticated 据我所知WebSecurity只是一个包
  • 显示 kivy 滑块值的变化 [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我想知道是否可以将 kivy 微调器值显示为移动标签 以便用户确切地知道滑块的当前值是什么 Thanks 您只需将侦听器绑定到值更改事件
  • Flowtype 函数可能会抛出错误

    有什么方法可以明确定义函数可以抛出错误 显然任何函数都可以抛出错误 但我想明确定义一个函数被设计为抛出并且可能根本不返回值 async function falseThrow promise Promise
  • 如何根据 NSString 类型键测试属性是否存在和类型?

    在我寻求更新 iOS 项目中的核心数据模型时 我在服务器上查询 JSON 对象 这些对象在某种程度上与我的模型的托管实体相对应 我追求的最终结果是从 JSON 输出获得可靠的更新解决方案 对于这个问题中的示例 我将命名核心数据管理对象exi