问题描述
我正在将一个应用程序从Objective-C切换到Swift,我有几个具有存储属性的类别,例如:
I am switching an application from Objective-C to Swift, which I have a couple of categories with stored properties, for example:
@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中创建了一些解决方案。
As Swift extensions don't accept stored properties like these, I don't know how to maintain the same structure as the Objc code. Stored properties are really important for my app and I believe Apple must have created some solution for doing it in Swift.
正如jou所说,我所寻找的实际上是使用关联对象,所以我做了(在另一个上下文中):
As said by jou, what I was looking for was actually using associated objects, so I did (in another context):
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:
But I get an EXC_BAD_ACCESS when doing:
class UIBubble : UIView {
required init(coder aDecoder: NSCoder) {
...
self.layer.shapeLayer = CAShapeLayer()
...
}
}
任何想法?
推荐答案
关联对象API使用起来有点麻烦。您可以使用帮助程序类删除大部分样板文件。
Associated objects API is a bit cumbersome to use. You can remove most of the boilerplate with a helper class.
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类:
Provided that you can "add" a property to objective-c class in a more readable manner:
extension SomeType {
private static let association = ObjectAssociation<NSObject>()
var simulatedProperty: NSObject? {
get { return SomeType.association[self] }
set { SomeType.association[self] = newValue }
}
}
这篇关于如何在Swift中存储属性,就像我在Objective-C上一样?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!