以下是發(fā)生異常的代碼
import UIKit
extension NSObject {
// MARK: - 定義一個類屬性作為閉包容器
class XYPropertyBlockContainer {
var viewModelBlock : ViewModelBlock?
var viewMangerInfosBlock : ViewMangerInfosBlock?
var viewModelInfosBlock : ViewModelInfosBlock?
}
}
問題描述:
Swift項(xiàng)目中再給NSobject類extension中添加類屬性作為閉包容器后狈定,在外界創(chuàng)建給這個閉包容器賦值時颂龙,發(fā)生奔潰,異常內(nèi)容如下:
*** NSForwarding: warning: object 0x17027acc0 of class '_TtCE10MVVMExapleCSo8NSObject24XYPropertyBlockContainer' does not implement methodSignatureForSelector: -- trouble ahead
Unrecognized selector -[_TtCE10MVVMExapleCSo8NSObject24XYPropertyBlockContainer copy]
問題分析:
1.通過異常信息可以發(fā)現(xiàn)是XYPropertyBlockContainer類未實(shí)現(xiàn)copy方法導(dǎo)致的纽什,XYPropertyBlockContainer是我定義的閉包容器類
2.原因這個類我未讓它繼承自NSObject措嵌,當(dāng)我讓其繼承自NSObjcet后,再次運(yùn)行時芦缰,再報(bào)異常reason: '-[_TtCE10MVVMExapleCSo8NSObject24XYPropertyBlockContainer copyWithZone:]: unrecognized selector sent to instance
3.最后讓XYPropertyBlockContainer
類繼承自NSObjcet
且遵守NSCopying
協(xié)議企巢,重寫copy(with zone: NSZone? = nil) -> Any
方法解決
解決異常后的代碼
import UIKit
extension NSObject {
typealias ViewModelBlock = () -> Void
typealias ViewMangerInfosBlock = () -> Void
typealias ViewModelInfosBlock = () -> Void
// MARK: - 定義一個類屬性作為block容器
class XYPropertyBlockContainer: NSObject, NSCopying {
func copy(with zone: NSZone? = nil) -> Any {
return self
}
var viewModelBlock : ViewModelBlock?
var viewMangerInfosBlock : ViewMangerInfosBlock?
var viewModelInfosBlock : ViewModelInfosBlock?
}
// MARK: - 關(guān)聯(lián)屬性的key
private struct RunTimeKey {
static let blockContainerKey = UnsafeRawPointer(bitPattern: "blockContainerKey".hashValue)
static let viewMangerDelegateKey = UnsafeRawPointer(bitPattern: "viewMangerDelegate".hashValue)
static let viewModelDelegateKey = UnsafeRawPointer(bitPattern: "viewModelDelegateKey".hashValue)
static let xy_viewMangerInfosKey = UnsafeRawPointer(bitPattern: "xy_viewMangerInfosKey".hashValue)
static let xy_viewModelInfosKey = UnsafeRawPointer(bitPattern: "xy_viewModelInfosKey".hashValue)
static let xy_mediatorKey = UnsafeRawPointer(bitPattern: "xy_mediatorKey".hashValue)
}
/// 閉包容器屬性
var propertyBlockContainer : XYPropertyBlockContainer? {
set {
objc_setAssociatedObject(self, RunTimeKey.blockContainerKey, newValue, .OBJC_ASSOCIATION_COPY_NONATOMIC)
}
get {
if let blockContainer = objc_getAssociatedObject(self, RunTimeKey.blockContainerKey) as? XYPropertyBlockContainer {
return blockContainer
}
return nil
}
}
}
注意:外界給閉包容器中的閉包賦值或者調(diào)用時,需要先創(chuàng)建閉包容器
@IBAction func btnClick(_ sender: Any) {
// 傳遞事件 通過閉包
if self.propertyBlockContainer == nil {
self.propertyBlockContainer = XYPropertyBlockContainer()
self.propertyBlockContainer?.viewModelInfosBlock = {
print("1+2")
}
self.propertyBlockContainer?.viewModelBlock = {
print("1+3")
}
self.propertyBlockContainer?.viewMangerInfosBlock = {
print("1+4")
}
self.propertyBlockContainer?.viewMangerInfosBlock!()
self.propertyBlockContainer?.viewModelBlock!()
self.propertyBlockContainer?.viewModelInfosBlock!()
}