我将应用程序从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() ... } }
有任何想法吗?
关联对象API使用起来有点麻烦。您可以使用帮助程序类删除大部分样板。
public final class ObjectAssociation<T: AnyObject> { private let policy: objc_AssociationPolicy /// - Parameter policy: An association policy that will be used when linking objects. public init(policy: objc_AssociationPolicy = .OBJC_ASSOCIATION_RETAIN_NONATOMIC) { self.policy = policy } /// Accesses associated object. /// - Parameter index: An object whose associated object is to be accessed. public subscript(index: AnyObject) -> T? { get { return objc_getAssociatedObject(index, Unmanaged.passUnretained(self).toOpaque()) as! T? } set { objc_setAssociatedObject(index, Unmanaged.passUnretained(self).toOpaque(), newValue, policy) } } }
前提是您可以以更易读的方式将属性“添加”到objective-c类:
extension SomeType { private static let association = ObjectAssociation<NSObject>() var simulatedProperty: NSObject? { get { return SomeType.association[self] } set { SomeType.association[self] = newValue } } }
至于解决方案:
extension CALayer { private static let initialPathAssociation = ObjectAssociation<CGPath>() private static let shapeLayerAssociation = ObjectAssociation<CAShapeLayer>() var initialPath: CGPath! { get { return CALayer.initialPathAssociation[self] } set { CALayer.initialPathAssociation[self] = newValue } } var shapeLayer: CAShapeLayer? { get { return CALayer.shapeLayerAssociation[self] } set { CALayer.shapeLayerAssociation[self] = newValue } } }