我正在将一个应用程序从 Objective-C 切换到 Swift,我有几个具有存储属性的类别,例如:
@interface UIView (MyCategory)
- (void)alignToView:(UIView *)view
alignment:(UIViewRelativeAlignment)alignment;
- (UIView *)clone;
@property (strong) PFObject *xo;
@property (nonatomic) BOOL isAnimating;
@end
由于 Swift 扩展不接受像这样的存储属性,我不知道如何保持与 Objc 代码相同的结构。存储属性对我的应用程序非常重要,我相信 Apple 一定已经创建了一些解决方案来在 Swift 中实现这一点。
正如 jou 所说,我正在寻找的实际上是使用关联对象,所以我做了(在另一个上下文中):
import Foundation
import QuartzCore
import ObjectiveC
extension CALayer {
var shapeLayer: CAShapeLayer? {
get {
return objc_getAssociatedObject(self, "shapeLayer") as? CAShapeLayer
}
set(newValue) {
objc_setAssociatedObject(self, "shapeLayer", newValue, UInt(OBJC_ASSOCIATION_RETAIN))
}
}
var initialPath: CGPathRef! {
get {
return objc_getAssociatedObject(self, "initialPath") as CGPathRef
}
set {
objc_setAssociatedObject(self, "initialPath", newValue, UInt(OBJC_ASSOCIATION_RETAIN))
}
}
}
但是我在执行以下操作时得到了 EXC_BAD_ACCESS:
class UIBubble : UIView {
required init(coder aDecoder: NSCoder) {
...
self.layer.shapeLayer = CAShapeLayer()
...
}
}
有什么想法吗?
最佳答案
与在 Objective-C 中一样,您不能将存储的属性添加到现有类中。如果你正在扩展一个 Objective-C 类(UIView
绝对是一个),你仍然可以使用 Associated Objects模拟存储的属性:
对于 Swift 1
import ObjectiveC
private var xoAssociationKey: UInt8 = 0
extension UIView {
var xo: PFObject! {
get {
return objc_getAssociatedObject(self, &xoAssociationKey) as? PFObject
}
set(newValue) {
objc_setAssociatedObject(self, &xoAssociationKey, newValue, objc_AssociationPolicy(OBJC_ASSOCIATION_RETAIN))
}
}
}
关联键是一个指针,对于每个关联来说应该是唯一的。为此,我们创建了一个私有(private)全局变量,并将其内存地址用作 &
运算符的键。查看Using Swift with Cocoa and Objective-C
有关如何在 Swift 中处理指针的更多详细信息。
已更新 Swift 2 和 3
import ObjectiveC
private var xoAssociationKey: UInt8 = 0
extension UIView {
var xo: PFObject! {
get {
return objc_getAssociatedObject(self, &xoAssociationKey) as? PFObject
}
set(newValue) {
objc_setAssociatedObject(self, &xoAssociationKey, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN)
}
}
}
已更新 Swift 4
在 Swift 4 中,它变得更加简单。 Holder 结构将包含我们的计算属性将向世界公开的私有(private)值,从而给人一种存储属性行为的错觉。
extension UIViewController {
struct Holder {
static var _myComputedProperty:Bool = false
}
var myComputedProperty:Bool {
get {
return Holder._myComputedProperty
}
set(newValue) {
Holder._myComputedProperty = newValue
}
}
}
关于ios - 如何在 Swift 中存储属性,就像在 Objective-C 中一样?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25426780/