这段时间做征收平台项目,其中有个需求是比较两个类之间所有的属性是否相等,前几天做的是如下
class A:NSObject {
var a:String
var b:Int
var c:Date
.
.
.
//有几十个var,要疯了
static func == (lhs:A,rhs:A) -> Bool {
return lhs.a == rhs.a && lhs.b == rhs.b && lhs.c == rhs.b ....//好无聊阿,浪费时间
}
}
大问题:是这样的class, 有几十个......
有没有其它方法,可以懒一些,
runtime
思路
我们可以用runtime遍历这样的类的属性,再把属性值给取出来做比较.
0. 原料:
class TestObj:NSObject {
var str:String = "string"
var number:Int = 34343
var date:Date = Date()
var list:[String] = ["d","f"]
init(date:Date) {
self.date = date
super.init()
}
}
1.首先要把类中的属性拿出来
var count:UInt32 = UInt32.max //这里用来保存类中有几个可拿的属性
let firstPropertyPointer = class_copyPropertyList(TestObj.self,&count)
// firstPropertyPointer,就是数组一样指向第一个属性的地址
把count 打印出来看看.
然后看到的是
"0" .....
咋回事?
原来是runtime只在objective-c里生效,那把所有属性加上@objc
class TestObj:NSObject {
@objc var str:String = "string"
@objc var number:Int = 34343
@objc var date:Date = Date()
@objc var list:[String] = ["d","f"]
init(date:Date) {
self.date = date
super.init()
}
}
再打印count
看一下,
现在看到
"4"
正常了.
2.可以遍历一样属性了,看看
for i in 0 ..< count {
let pointer = firstPropertyPointer.advanced(by:Int(i))//得到属性的指针(地址)
let property = pointer.move()//得到property,(地址指向的值)
let name = String(cString:property_getName(property))//得到属性的名字
}
这样就可以打印出这个类里标有@objc
的所有属性的名字了
3.再向下就是得到值了
let obj = TestObj(date:Date())
obj.value(forKey:name)
4.比较
let value = obj.value(forKey:name)
这个value
出来的是Any?
,不能直接比较.所有objective-C里的都是类,是类就是继承至NSObject
,那这样的话就可以如下写
let value = obj.value(forKey:name) as! NSObject
5.综合
class TestObj: NSObject {
@objc var obj:String = "fd"
@objc var number:Int = 12312
@objc var date:Date = Date()
@objc var list:[String] = ["d","f"]
init(date:Date){
super.init()
self.date = date
}
static func == (lhs:TestObj,rhs:TestObj) -> Bool{
var count:UInt32 = UInt32.max
guard let firstPropertyPointer = class_copyPropertyList(TestObj.self, &count) else{
return false
}
for i in 0 ..< count {
let propertyP = firstPropertyPointer.advanced(by: Int(i))
let property = propertyP.move()
let propertyName = String(cString:property_getName(property))
let lValue = lhs.value(forKey: propertyName) as! NSObject
let rValue = rhs.value(forKey: propertyName) as! NSObject
if lValue != rValue {
return false
}
}
free(firstPropertyPointer)//释放内存,这是C语言层面的,不会自动释放内存
return true
}
}
网友评论