如何判断一个具有很多属性的对象(自身)是否发生了改变?

2024-05-07

问题的简短版本:
我有一个带有大量声明属性的类,我想跟踪它是否有任何更改,以便当我调用save方法,当不需要时它不会写入数据库。我如何更新isDirty财产无需为所有声明的属性编写自定义设置器?

问题的较长版本:
假设我有一堂这样的课:

@interface MyObject : NSObject
{
@property (nonatomic, retain) NSString *myString;
@property (nonatomic, assign) BOOL     myBool;
// ... LOTS more properties
@property (nonatomic, assign) BOOL     isDirty;
}

...

@implementation MyObject
{
@synthesize myString;
@synthesize myBool;
// ... LOTS more synthesizes :)
@synthesize isDirty;
}

尝试1
我的第一个想法是实施setValue:forKey:像这样:

- (void)setValue:(id)value forKey:(NSString *)key {
    if (![key isEqualToString:@"isDirty"]) {
        if ([self valueForKey:key] != value) {
            if (![[self valueForKey:key] isEqual:value]) {
                self.isDirty = YES;
            }
        }
    }
    [super setValue:value forKey:key];
}

除非您直接使用 setter 设置该值(即,myObject.myString = @"new string";), 在这种情况下setValue:forKey:没有被调用(我不知道为什么我认为它会被调用,哈哈)。

尝试2
观察自我的所有属性。

- (id)init
{
    // Normal init stuff
    // Start observing all properties of self
}

- (void)dealloc
{
    // Stop observing all properties of self
}

- (void)observeValueForKeyPath:(NSString *)keyPath 
                      ofObject:(id)object 
                        change:(NSDictionary *)change 
                       context:(void *)context
{
    // set isDirty to true
}  

我很确定这会起作用,但我认为必须有更好的方法。 :) 我还希望这是自动的,这样我就不必维护要监视的属性列表。我可以很容易地看到在维护这个属性时忘记将属性添加到列表中,然后尝试找出为什么我的对象有时没有被保存。

希望我忽略了解决这个问题的更简单的方法!

最终解决方案
请参阅下面我的回答,了解我对此问题的最终解决方案。它基于 Josh Caswell 提供的答案,但它是一个有效的示例。


一点自省应该会有所帮助。这运行时函数 http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/ObjCRuntimeRef/Reference/reference.html可以为您提供所有对象属性的列表。然后你可以用它们告诉 KVOdirty is 依赖的 http://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/KeyValueObserving/Articles/KVODependentKeys.html#//apple_ref/doc/uid/20002179-SW3在那个名单上。这避免了必须手动更新属性列表的可维护性问题。需要注意的是,与任何其他涉及 KVO 的解决方案一样,如果 ivar 直接更改,您将不会收到通知 - 所有访问must通过 setter 方法。

注册观察self's dirty关键路径在init,并添加此方法,创建并返回一个NSSet包含类的所有属性的名称(除了@"dirty", 当然)。

#import <objc/runtime.h>

+ (NSSet *)keyPathsForValuesAffectingDirty 
{
    unsigned int num_props;
    objc_property_t * prop_list;
    prop_list = class_copyPropertyList(self, &num_props);

    NSMutableSet * propSet = [NSMutableSet set];
    for( unsigned int i = 0; i < num_props; i++ ){
        NSString * propName = [NSString stringWithFormat:@"%s", property_getName(prop_list[i])];
        if( [propName isEqualToString:@"dirty"] ){
            continue;
        }
        [propSet addObject:propName];
    }
    free(prop_list);

    return propSet;
}

现在观察dirty每当设置此类的任何属性时都会触发。 (请注意,超类中定义的属性不包含在该列表中。)

您可以使用该列表单独注册为所有名称的观察者。

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

如何判断一个具有很多属性的对象(自身)是否发生了改变? 的相关文章

  • Swift:使用元组在单个 switch-case 中使用多个间隔

    有这样的代码 switch indexPath section indexPath row case 0 1 5 println in range default println not at all 问题是我可以在第二个元组值中使用多个间
  • 如何在 iOS 企业帐户中创建开发人员配置文件请求?

    我们有 iOS 企业帐户 现在我们想要向我们的团队添加一名开发人员 该开发人员将创建一个开发人员配置文件 问题是新添加的开发人员在他的苹果帐户中看不到配置文件标签 任何人都知道新添加的开发人员如何创建配置文件 感谢您 Steps 您可以通过
  • AutoLayout 将 UILabel 高度设置为零

    我有一个UILabel对于其他视图中的项目描述 所有内容均使用 Interface Builder 中的约束进行布局 您可以在下图中看到所有相关约束 行数也设置为0 我没有设置高度限制 因为我想要UILabel根据其包含的文本调整大小 相反
  • 使用仪器分配时 iOS 应用程序冻结

    当我想使用 Instruments Allocation 来分析应用程序的内存使用情况时 它在启动后立即冻结 它总是停留在启动屏幕 这是一个 Xamarin forms 应用程序 这是屏幕截图 其他信息 如果我创建一个新项目 然后使用 In
  • 如何在iOS中获得旋转UIView的完美X,Y位置

    我正在使用 CABasicanimation 来旋转 UIView 我正在使用这段代码 CABasicAnimation rotationAnimation CABasicAnimation animationWithKeyPath tra
  • uiscrollview 放大和缩小无法正常工作

    我有一个 uiscrollview 里面有一个 uiimageview 我希望用户能够放大图像 因为它是一个大图像 滚动视图只需要垂直滚动而不是水平滚动 在添加缩放效果之前 我有以下代码并且它按我想要的方式工作 void viewDidLo
  • 自定义选项卡栏上的“更多”菜单

    我在我的应用程序上使用选项卡栏 UITabBarController 我希望自定义单击 更多 按钮时出现的表格的外观 我已经研究出如何通过设置来更改更多屏幕上导航栏的外观 self moreNavigationController navi
  • 如何使用break语句停止内部和外部循环[重复]

    这个问题在这里已经有答案了 我使用的代码非常简单break内部循环 for int it 0 it lt 5 it for int it2 0 it2 lt 5 it2 if it2 2 break break here not it2 b
  • swift 中 pch 的替代品是什么?

    我想知道可以用什么来代替 swift 中的 pch 有没有 pch 的替代方案或方法可以快速摆脱导入 这样我们就不需要对所有类都这样做 我不想一直随身携带 进口 swift 中 pch 的最佳替代品是什么 您无法在 swift 中定义 宏
  • 预填充 UICollectionView 单元重用队列

    问题 我有一个应用程序 只有一个UICollectionView我第一次滚动它时很卡顿 我已将来源范围缩小到正在创建新单元格 2 的事实 使用initWithFrame 因为周围没有可以重复使用的细胞 初始滚动后 重用队列不为空 单元格可以
  • Gmail 中删除了 iOS 深层链接

    我正在尝试发送一封带有深层链接的电子邮件到我的 iOS 应用程序 使用 myapp 格式从电子邮件中将其打开 它可以在任何 iOS 邮件客户端 邮件 邮箱等 中运行 即点击它打开应用程序 但不能在 Gmail 应用程序 甚至网络 中运行 因
  • 无法为 FacebookSDK 4 构建模块“FBSDKCoreKit”

    我在将 Facebook SDK 3 更新到 4 时遇到问题 当我添加框架时 它已成功添加 但是当我添加头文件时出现错误 无法构建模块 FBSDKCoreKit 不知道原因 在设置中 允许非模块化包含在框架模块中 设置为YES在构建设置中解
  • 如何处理 iPhone 屏幕尺寸/背景图像分辨率

    在 iPhoneX 之后 我真的很纠结于支持所有设备的图像尺寸和命名约定 有没有办法在 4 7 5 5 和 5 8 屏幕上使用 3x 图像 全屏图像视图应该使用的确切尺寸是多少 您可以使用图像 pdf格式 因此您只需要管理 1x 的单比例图
  • 重新安装我的 iPad 应用程序时,ApplicationIconBadgeNumber 未重置。

    我正在使用以下代码设置我的 applicationIconBadgeNumber UIApplication sharedApplication setApplicationIconBadgeNumber theIntToDisplay 问
  • 在 iPhone 上搜索 PDF

    经过两天尝试使用 Quartz 从 PDF 中读取注释后 我成功做到了并且发布我的代码 https stackoverflow com questions 4080373 get pdf hyperlinks on ios with qua
  • 在 swift ios 中播放远程 mp3 文件需要花费大量时间

    我有麻烦了 我想在我的应用程序中播放远程 mp3 文件 但 mp3 文件需要很长时间 大约 5 6 分钟 来播放 为什么 任何人都可以建议我应该做什么 import UIKit import AVFoundation class TestV
  • 适用于 iOS 的 MvvmCross 汉堡菜单

    我在用着https www marcbruins nl xamarin ios hamburger menu mvvmcross https www marcbruins nl xamarin ios hamburger menu mvvm
  • 获取在 iOS UIFont 中追踪字符的路径

    假设我在 iOS 应用程序中使用了自定义字体 Foo 我已将其添加到我的项目 plist 等中 并且我能够渲染UILabels之类的就很好了 现在 如果我想找出可以 追踪 该字体中的字母 P 的点序列 我将如何获得该点序列 例如 假设我想使
  • 将 MPMoviePlayerController 的视图添加到 UIView

    我想添加MPMoviePlayerController to a UIView 首先 我在 xib 文件中放置了一个视图 名为 youTubeView youtube播放器是MPMoviePlayerController youtubePl
  • iOS 上 Safari 中的 shift 键

    有没有办法在javascript中判断手机键盘上是否按下了shift键 并将其与大写锁定 按两次shift键 区分开来 一些事实 首先 让我们看一下有关 iOS 键盘的一些事实 我假设您已经知道了 当您进入键盘模式时 shift键始终处于激

随机推荐

  • 纹理不适用于网格 - OpenGL

    我正在使用 OpenGL Es 我已成功加载 obj 文件 网格 并且显示良好 但当我应用纹理时 它不显示 我添加了下面的代码 public void draw GL10 gl bind the previously generated t
  • 复制到其他计算机时无法在 WcfTestClient 中添加服务

    我想在另一台计算机上运行 WcfTestClient VS2012 中包含的一个 而不安装 VS2012 这可能吗 在我已经安装了 NET 4 5 的机器上 但是当我尝试添加 Web 服务时 它给了我以下堆栈跟踪 Exception Tex
  • 是否可以仅使用密码进行身份验证,即使设备在 ios、swift 中具有 touch id 功能

    我要认证only使用PassCode甚至设备有Touch ID特征 我在用着 deviceOwnerAuthentication评估政策方法 当我使用这个时 如果用户已注册触摸 ID gt 始终要求提供触摸 ID 如果用户尚未注册 touc
  • Django- CMS:占位符中的插件位置

    我正在寻找一种方法来检查插件在 Django CMS 占位符中的位置 我发现这个问题检测占位符中的最后一个插件 https stackoverflow com questions 5543947 detect last plugin in
  • 将元组划分为多个元组的类型安全方法

    我们有一个特征 除其他外 还包含execute T lt Record Seq Session gt T Seq T 方法 其中Record是我们从数据库中检索的所有特征的超级特征 trait DbTrait val threadCount
  • 如何将Windows服务中的参数从Installer传递到Program.cs中的Main函数?

    我已成功将参数从 Installutil 传递到我的 serviceinstaller 但我似乎无法将这些参数传递到 Main string args 函数 这就是我尝试做到这一点的方法 如果有更好的方法来做我正在做的事情请告诉我 prot
  • Javascript 沙箱模式示例实现

    在 Stoyan Stefanov 的伟大著作 JavaScript Patterns 的第 101 页中 他解释了沙箱模式 我非常喜欢他的书 但我真的错过了一些现实生活中的例子 然后更好地理解他所谈论的内容 我正在寻找一个现实生活中的工作
  • 无法解析符号“servlet”

    我有一个新手大问题 当我尝试以下操作时 servlet 变成红色并指示 无法解析符号 servlet import javax servlet http import javax servlet ServletException 我的 ap
  • 一个在 Java 中进行 URL 查询字符串操作的好库 [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我需要用 Java 进行一些非常简单的 URL 操作 就像获取查询中参数的值或更新它一样 我希望在 commons lang 包中找到一个
  • 正在传输包... > 失败 以下步骤中发生错误。 `正在传输包...`(返回代码:2)未知错误

    当我在模拟器上部署 Tizen 项目时出现错误 正在传输包 gt 失败 在以下步骤中发生错误 Transferring the package 返回代码 2 未知错误 我该如何修复它 以及在我的模拟器中的开发人员模式下 这个问题的答案是 确
  • AndroidJUnit4 测试未找到

    我像这样注释了我的课程 RunWith AndroidJUnit4 class public class WorkdayProviderTest 此外 还注释了我的测试方法 如下所示 Test public void insert data
  • jQuery醉酒:手动触发器和delayIn

    我正在使用 jQuery 的 Tipsy 插件 每当我尝试使用手动触发器和delayIn调用醉酒时 delayIn似乎不起作用 interest tipsy trigger manual gravity n html true delayI
  • 如何计算分数?

    这个问题比任何编程语言都更与逻辑相关 如果问题不适合论坛 请告诉我 我将删除它 我必须编写一个逻辑来计算博客奖网站的博客分数 一个博客可能会获得多个奖项类别的提名 并由评审团以 1 到 5 的等级进行同行评审或评级 1 表示他们完全不喜欢博
  • 在 Oracle BI Publisher 中将数字转换为单词

    我有一个要求 我需要将发票总金额显示为 rtf 中的文字 我尝试过 but it doesn t show any thing Is there any RTF Tag to do such a requirement on layout
  • rspec 不适用于设计用户身份验证

    我正在尝试使用 RSpec 来测试我的 Rails 应用程序 该应用程序使用设计用户身份验证 gem 以下是已捆绑的相关 gem 的列表 devise 3 4 1 rails 4 1 7 4 1 6 rspec 3 1 0 rspec co
  • 使用 Spring Security 滑动过期

    我正在使用 Spring Security 我注意到 当用户登录时 身份验证 cookie 的有效期约为一天 它似乎并没有 刷新 这个过期日期 cookie 在一天后过期 即使在当天结束前 5 分钟我已经通过安全 URL 向服务器发出了请求
  • 使用 textbox_keypress 过滤绑定源或绑定列表

    我使用 winforms 和 c 如何过滤绑定源或绑定列表 带有文本框文本 我的意思是 当我在文本框中输入时 我的网格正在使用 Like 方法而不是 equal 方法进行过滤 thanks 我使用委托来解决这个问题 一些代码如下所示 Lis
  • 在单独的线程上显示 WPF-“NotifyIcon”

    我目前正在开发一个 Office 加载项 我需要显示一个显示进度的通知对话框 我正在使用Philipp Sumi 的 wpf notifyicon http www codeproject com Articles 36468 WPF No
  • 给出 HTML 和 Xpath 时突出显示

    给定 HTML 作为字符串 Xpath 和偏移量 我需要强调这个词 在下面的例子中我需要强调Child 1 HTML 文本 h2 Children h2 Joe has three kids br ul li a href Child 1
  • 如何判断一个具有很多属性的对象(自身)是否发生了改变?

    问题的简短版本 我有一个带有大量声明属性的类 我想跟踪它是否有任何更改 以便当我调用save方法 当不需要时它不会写入数据库 我如何更新isDirty财产无需为所有声明的属性编写自定义设置器 问题的较长版本 假设我有一堂这样的课 inter