[英]dealloc/deinit called early when using objc_setAssociatedObject in swift
[英]Swift 3.0: “objc_setAssociatedObject” issue
import UIKit
import ObjectiveC
var SubRowObjectKey: String = "subRow"
extension IndexPath {
var subRow: Int {
get {
let subRowObj = objc_getAssociatedObject(self, &SubRowObjectKey)
if subRowObj != nil {
return (subRowObj as! Int)
}
return 0
}
set {
let subRowObj = (newValue as NSInteger)
objc_setAssociatedObject(self, &SubRowObjectKey, subRowObj, .OBJC_ASSOCIATION_RETAIN)
}
}
static func indexPathForSubRow(_ subRow: NSInteger, inRow row: NSInteger, inSection section: NSInteger) -> IndexPath {
var indexPath = IndexPath(row: row, section: section)
indexPath.subRow = (subRow as Int)
print(subRow)
print(indexPath.subRow)
return indexPath
}
}
let indexPath = IndexPath.indexPathForSubRow(5, inRow: 1, inSection: 2)
print(indexPath.subRow)
在Xcode版本8.2.1和Swift 3.0中測試
任何幫助將不勝感激。
IndexPath
是一個結構,它不支持關聯的對象。 您可以通過直接嘗試回讀設置對象來輕松地在setter中檢查它:
set {
let subRowObj = (newValue as NSInteger)
objc_setAssociatedObject(self, &SubRowObjectKey, subRowObj, .OBJC_ASSOCIATION_RETAIN)
let subRowObj2 = objc_getAssociatedObject(self, &SubRowObjectKey)
print(subRowObj2 ?? "nil") // prints "nil"
}
即使setter中的代碼有效 ,整個構造仍然不成立:由於結構在傳輸/分配時被復制(至少通過寫入機制上的復制進行修改),因此相關對象將不包含在復制,所以你遲早會丟失這些信息。
然而,不是擴展IndexPath
你可以擴展NSIndexPath
然后工作正常 - 但我想這不是你想要的,因為你想影響從表視圖得到的IndexPath ...
根據maddy的回答,這是我的IndexPath擴展,它添加了一個subRow屬性。
extension IndexPath {
init(subRow: Int, row: Int, section: Int) {
self.init(indexes: [IndexPath.Element(section), IndexPath.Element(row), IndexPath.Element(subRow)])
}
var subRow: Int {
get { return self[index(at: 2)] }
set { self[index(at: 2)] = newValue }
}
var row: Int {
get { return self[index(at: 1)] }
set { self[index(at: 1)] = newValue }
}
var section: Int {
get { return self[index(at: 0)] }
set { self[index(at: 0)] = newValue }
}
private func index(at idx: Int) -> IndexPath.Index {
return self.startIndex.advanced(by: idx)
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.