Swift快速为类扩展属性

Swift快速为类扩展属性,第1张

概述在程序编写过程中,我们常常需要为已有的类扩展新的属性。通常我们的解决办法是先声明一个Key,然后使用 objc_getAssociatedObject 和 objc_setAssociatedObject来设置属性。相对来说比较麻烦,因为扩展属性的需求比较大,所以笔者对这两个方法做了一些封装,减少了很多代码。 使用 首先我们来看看封装后如何使用。 把Property.swift拖到你的项目中 让类
在程序编写过程中,我们常常需要为已有的类扩展新的属性。通常我们的解决办法是先声明一个Key,然后使用 objc_getAssociatedobjectobjc_setAssociatedobject来设置属性。相对来说比较麻烦,因为扩展属性的需求比较大,所以笔者对这两个方法做了一些封装,减少了很多代码。
使用

首先我们来看看封装后如何使用。

把Property.swift拖到你的项目中 让类/Protocol 继承 Property 声明你的属性,get/set参照如下代码
extension VIEw:Property{    var margin : Int{        get{ return get0() }        set{ set0(newValue)}    }}

是不是非常简单?不过在使用这个Property之前,一定要看清楚注意事项哦。
Property里面默认封装了设置三个属性的方法。
扩展前三个属性的时候分别是 get0() & set0()、get1() & set1()、get2() & set2()
那么超过三个属性应该如何设置呢?

方案1:扩展Property的方法。 方案2:使用Property默认的get() set(),并且需要传入一个变量指针,参考如下代码:
var test : String{        get{ return get(&keyPoint) }        set{ set(&keyPoint,newValue)}    }

也还是比较简单的,毕竟为一个类扩展超过三个以上的属性的需求还是比较小的。

封装过程

首先我们看看,扩展属性通常使用的代码

struct XKeys {    static var common : String = "common"}extension AbstractProtocol{    var common : String{        get{            return objc_getAssociatedobject(self,&XKeys.common) as! String        }        set{            objc_setAssociatedobject(self,&XKeys.common,newValue,objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)        }    }

在复制粘贴了多次这样的代码之后,我实在厌倦了这样扩展属性的方式,然后开始了自己的封装。
首先我发现声明一个Key之后,可以给多个类共用,没有任何影响,但是如果同一个类的不同属性,使用了相同的Key,就会有问题了。所以首先要保证同一个类,扩展出来的不同属性的key值必须要不同。
所以我想到用一个数组来保存key,不过很可惜失败了。

最开始封装Property的时候是直接声明了一个类,写了一些静态方法。然后在get set中调用。

class Property2 {    static func get<T : Any>(_ key: UnsafeRawPointer) -> T{        return objc_getAssociatedobject(self,key) as! T    }    static func set<T : Any>(_ key: UnsafeRawPointer,_ newValue : T) {        objc_setAssociatedobject(self,key,objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)    }}

不过测试过程中发现一些问题,这个self实际应该使用被扩展的对象的类的self,所以经过修改后,代码如下:

class Property2 {    static func get<T : Any>(_ o : Any,_ key: UnsafeRawPointer) -> T{        return objc_getAssociatedobject(o,key) as! T    }    static func set<T : Any>(_ o : Any,_ key: UnsafeRawPointer,_ newValue : T) {        objc_setAssociatedobject(o,objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)    }}

调用的时候:

var common : String{    get{        return Property2.get(self,&XKeys.common)    }    set{        Property2.set(self,newValue)    }}

感觉封装了跟没封装基本差不多啊。
有没有办法能省略Property和self呢,于是我想到了Protocol,然后让类去继承我的Property,这样就可以省略掉这两项了。不过Key还是要传递,所以我默认声明了三个key,再提供一个需要传递key的方法。最后封装好的代码为:

//  Property.swift////  Created by Fancy on 26/1/18.//  copyright © 2018年 Artifex Software,Inc. All rights reserved.import UIKitstruct PropertyKey{    static var key0 : VoID?    static var key1 : VoID?    static var key2 : VoID?}protocol Property{}extension Property{    func get<T : Any>(_ key: UnsafeRawPointer) -> T{        return objc_getAssociatedobject(self,key) as! T    }    func set<T : Any>(_ key: UnsafeRawPointer,objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)    }    func get0<T : Any>() -> T{        return objc_getAssociatedobject(self,&PropertyKey.key0) as! T    }    func set0<T : Any>(_ newValue : T) {        objc_setAssociatedobject(self,&PropertyKey.key0,objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)    }    func get1<T : Any>() -> T{        return objc_getAssociatedobject(self,&PropertyKey.key1) as! T    }    func set1<T : Any>(_ newValue : T) {        objc_setAssociatedobject(self,&PropertyKey.key1,objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)    }    func get2<T : Any>() -> T{        return objc_getAssociatedobject(self,&PropertyKey.key2) as! T    }    func set2<T : Any>(_ newValue : T) {        objc_setAssociatedobject(self,&PropertyKey.key2,objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)    }}
结语

整个封装过程没有什么高科技含量的 *** 作,写文章做点记录,希望能给到需要的人帮助。

总结

以上是内存溢出为你收集整理的Swift快速为类扩展属性全部内容,希望文章能够帮你解决Swift快速为类扩展属性所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1055599.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-25
下一篇 2022-05-25

发表评论

登录后才能评论

评论列表(0条)

保存