如何根据 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 类型键测试属性是否存在和类型? 的相关文章

  • 在 init 和 dealloc 方法中有效使用访问器?

    我现在从多个来源 stackoverflow com cocoa dev 文档 博客等 听说 在 init 和 dealloc 方法中使用访问器和设置 foo setFoo 是 错误的 我知道如果这样做 很可能会混淆正在观察该属性的其他对象
  • 我可以向 YAML Swagger 对象添加版本吗?

    我正在创建一个 API 定义 并且我想将规范模型拆分为不同的文档并使用 JSON 指针 ref 来重用它们 我需要找到一种在 YAML 文件中添加版本的方法 例如 pj yaml pJType verison 1 0 type object
  • Gradle 额外属性在子项目中定义的自定义任务中不可见

    我正在尝试在多个 Gradle 任务之间重用通用逻辑 类似于中建议的内容这个答案 https stackoverflow com a 13072481 但我遇到了额外项目属性不可见的问题 归根结底 问题就在这里 假设我有一个根 Gradle
  • CSS 选择器的优先级是什么

    CSS 问题 如果两个不同的选择器应用于一个元素 谁会获胜 我知道这不应该发生 但我想调整遗留应用程序 而 CSS 却处于中间位置 The 血淋淋的细节 http www w3 org TR CSS21 cascade html casca
  • CSS:不是属性[重复]

    这个问题在这里已经有答案了 我有一些 HTML 表格 这些表没有 CSS 类 两个表有width 100 属性 其他表没有width属性 仅使用 CSS 我需要设置没有的表格的宽度width 100 像这样的事情 table not wid
  • CSS“>”与“>”?

    In CSS a gt b是相同的 a gt b 但这两个符号中哪一个更正确呢 我看到在 Chrome 开发者工具中使用了第二个变体 两者都不是 更正确 两者同样有效 唯一的一点就是spec http www w3 org TR selec
  • 如何使用动态名称实现 property() (在 python 中)

    我正在对单个神经元进行模拟编程 因此我必须处理很多参数 现在的想法是我有两个类 一个用于 SingleParameter 一个用于参数集合 我使用 property 来轻松访问参数值并使代码更具可读性 这非常适合 sinlge 参数 但我不
  • Spring MVC application.properties 不会被配置文件 application-dev.properties 覆盖

    我正在寻找一种根据 JVM 环境变量配置不同 application properties 文件的方法 我在 Spring 参考资料中找到了这个文档 除了 application properties 文件之外 还可以使用命名约定 appl
  • 从 PHP 中具有动态类名的类获取静态属性

    我有这个 一个保存类名的字符串变量 classname 一个字符串变量包含属性名称 propertyname 我想从该类获取该属性 问题是 该属性是静态的 我不知道该怎么做 如果该属性不是静态的 则它将是 classname gt prop
  • 为什么相邻同级选择器不起作用? [关闭]

    Closed 这个问题需要细节或清晰度 help closed questions 目前不接受答案 根据相邻同级选择器的定义 以下代码应该可以工作 然而事实并非如此 我似乎没有发现任何错误 p p p This is the sibling
  • 选择一个元素及其所有后代元素

    选择一个元素and它的所有后代元素 media media color f00 我是否只能使用一个选择器 而不是用逗号分隔两个选择器 我正在寻找一种更有效的方式来输入此内容 With XPath https www w3schools co
  • 使用 cURL 检查 FTPS 站点上是否存在文件

    我正在使用 cURL 应用程序下载多个 csv 文件 我想找到一种方法来在开始下载之前检查文件是否存在于 ftps 站点上 如果它不存在 我想找到一种方法让 cURL 定期再次检查 我试图坚持使用 cURL 命令 因为我真的不擅长 Net
  • iOS——codeSense 中自动合成属性的“添加”方法

    我刚刚创建了一个具有以下属性的 iOS 类 property nonatomic strong NSString foo property nonatomic strong NSObject bar property nonatomic C
  • 条件“可浏览”属性

    有没有办法使 可浏览 属性成为有条件的 以便应用它的属性有时会出现在属性页中 有时不会出现 谢谢 我不确定这是否适用于您的情况 但您可以通过调用下面的函数在运行时调整 可浏览 装饰
  • 使用 Selenium WebDriver 带有 contains() InvalidSelectorException 的 CSS 定位器

    我在学习硒网络驱动程序并尝试编写一个简单的测试脚本 目的是为了得到About Google链接上Gmail页面以便练习CSS 定位器 这是代码 public class GoogleSearch public static void mai
  • Selenium find_elements_by_css_selector 返回一个空列表

    我正在尝试选择包含以下内容的所有 idcoupon link关键字与以下脚本 from selenium import webdriver from selenium webdriver common keys import Keys dr
  • 通过调用 shell 脚本设置 ant 属性?

    有没有办法通过捕获 shellscript 的输出来设置 ant 属性 或另一个蚂蚁任务 像这样的事情
  • 如何在样式定义中排除包含所有子级的类

    我有一个像这样的文件 div div class abc div div div div 我想要做的是将样式仅应用于第一个 div 我尝试使用div not abc abc div not abc not abc div not abc d
  • Xcode:如何创建出现在另一个视图控制器中的弹出视图控制器

    基本上我想做的是 假设我有一个名为 V1 的视图控制器 它内部有一个常规视图和一个按钮 现在 当您点击该按钮时 我希望该按钮创建一个操作 在同一视图控制器 V1 中弹出另一个名为 V2 的视图控制器 V2 的尺寸会缩小一些 使其不会填满整个
  • 如何通过反射获取当前属性名称?

    当我通过反射进入其中时 我想获取属性名称 是否可以 我有这样的代码 public CarType Car get return Wheel this Wheel set this Wheel value 因为我需要更多这样的属性 所以我想做

随机推荐

  • 如何组织大型 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