如何比较两个 NSObject 的结构/属性的相等性
我有一个数据库模型 NSObject 类,具有 100 个左右的属性——主要是 NSString,但也有一些 NSDate。 我试图确定一种简单的方法来比较数据库的任何两个给定成员对象。例如,如果用户编辑 objectA 中的属性,我希望能够与数据库中的原始对象进行比较,以查看是否进行了更改。
[objectA isEqual:objectB]
不返回有效结果
,所以我所做的是重写类定义中的 isEqual 方法,但这似乎很乏味。我还必须检查每个属性,看看其中一个属性是否为 Nil(带有日期),因为如果其中之一为 Nil,则比较不会起作用。
I have a database model NSObject class with 100 or so properties -- mostly NSStrings but some NSDates.
I'm trying to determine an easy way to compare any two given member objects of the database. For instance if user edits a property in objectA I want to be able to compare to the original object in the DB to see if changes were made.
[objectA isEqual:objectB]
does not return valid results
so what I did is override the isEqual method in the class definition but it seems to be tedious to do. I also have to check each property to see if either one is Nil with dates since comparisons don't see to work if one of them is Nil.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
也许您可以使用 KVC 使
isEqual
重写更加简洁。首先,您必须准备一个代表每个属性名称的 NSString 数组,可能在 init 方法中。
在
isEqual
方法中,您可以检查所有属性名称并使用valueForKey
方法获取属性值。这样,您就不必执行 100 个相同的序列。
上面的代码非常粗糙(没有空检查。没有参数对象的类类型检查等),并且没有经过测试,但我希望你明白。
另一件需要注意的事情是,您还必须覆盖
hash
方法。以下是 NSObject 文档Maybe you can use KVC to make the
isEqual
override a little more concise.First, you have to prepare an array of NSString that represents each property name, probably in
init
method.In
isEqual
method, you go over all property names and get the property value usingvalueForKey
method.This way, you do not have to implement 100 of the same sequence.
The code above is very coarse (doesn't have null check. doesn't have class type check of the parameter object etc.), and not tested, but I hope you get the idea.
Another thing to note is that you have to override
hash
method as well. Following is the quote from the NSObject documentationisEqual:比较指针,这意味着除非它们是完全相同的对象,否则它们将不相等。您想要做的是使用
compare:
方法,它实际上会比较 NSStrings 的内容。查看文档,您可以为区分大小写或不区分大小写的搜索指定多个选项。 NSDate 有一个类似的方法比较,但你也可以这样做:看看 文档 也有关于该文档。
编辑:
NSStrings 还有一个 isEqualToString: 方法,因此您可以执行以下操作:
这将返回 YES 或 NO,具体取决于 objectA 和 objectB 的 unicode 是否完全相同。如果您只是测试精确副本之间的相等性,如果您想基于某些选项(例如区分大小写)进行比较,这将是一个更好的选择
compare:
是一个更好的选择。isEqual:
compares pointers, meaning unless they are exactly the same object they will not be equal. What you want to do is use thecompare:
method, that will actually compare the contents of the NSStrings. Take a look at the documentation, there are several options you can specify for even case sensitive or not sensitive searching. NSDate has a similar method compare, but you can also do:Take a look at the documentation on that one too.
Edit:
NSStrings also have an
isEqualToString:
method so you can do:That will return YES or NO depending on if the unicode for both objectA and objectB is exactly the same. This would be a better option if you were just testing for equality among exact copies, if you wanted to do comparison based on certain options like case sensitivity
compare:
is a better choice.有一种基于
valueForKey:
的稍微不那么繁琐的方法,但它有自己的性能权衡。There's a slightly less tedious way based on
valueForKey:
, but it has its own performance tradeoffs.在这里发布工作代码以防万一它会帮助其他人——此代码说明一个或两个对象为空(不会使用 isEqual 进行比较):
在对象模型中合成 propertyNames:
使用 ProperyNames 的字符串数组初始化一次:
覆盖 isEqual: 方法
(此示例比较了我在模型中使用的对象类型 - 字符串、日期和图像):
您显然可以取出我放入用于调试的所有 NSLog。
感谢所有帮助我的人!
Posting Working Code here just in case it will help others -- this code accounts for one or both objects being null (which will not compare using isEqual):
synthesize propertyNames in the Object Model:
initialize once with array array of strings with ProperyNames:
Override the isEqual: method
(this example compares types of objects I'm using in my model -- strings, dates & images):
You can obviously take out all the NSLogs I put in for Debugging.
Thanks to all who helped me out!