当前位置: 首页 > 面试题库 >

如何在Swift中存储属性,就像在Objective-C中一样?

万嘉熙
2023-03-14
问题内容

我将应用程序从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 }
    }
}


 类似资料:
  • 问题内容: 简单地说,我有一个存储应用程序常量的结构,如下所示: 例如,可以通过调用在Swift代码中使用这些常量。但是在我的代码中,它还包含一些Objective- C类。所以我的问题是如何在Objective-C代码中使用这些常量? 如果这种声明常量的方法不好,那么在Swift和Objective-C代码中使用全局常量的最佳方法是什么? 问题答案: 可悲的是,你不能暴露,也不是Objectiv

  • 问题内容: 有什么方法可以在我的Swift项目中使用swift使用用Objective-C编写的CocoaPod吗? 我只是制作桥接头吗?如果可以,我可以在Swift中访问CocoaPod中的库定义的对象,类和字段吗? 问题答案: 您问题的基本答案是,可以,您可以使用CocoaPods构建的Objective-C代码。 更重要的问题是“如何使用此类库?” 这个问题的答案取决于您中的标志: 假设您要

  • 我正在尝试实现音频可视化器到AVAudioPlayer从许多天,尝试了不同的库,但没有成功。现在我发现了一个库displayer,但问题是它在Objective-C中,现在我不知道如何在swift代码中使用它。这里是图书馆https://github.com/agilie/displayers-audio-visualizers的链接。请在这方面指导我,或者在SWIFT中建议我一个好的可视化器。

  • 问题内容: 我注意到编译器不会让我用另一个存储的值覆盖存储的属性(这似乎很奇怪): 但是,我可以使用计算属性来执行此操作: 为什么不允许我再给它一个值? 为什么用存储的属性覆盖是可憎的,而要使用计算的一个犹太洁食呢?他们在想什么呢? 问题答案: 为什么不允许我再给它另一个值? 绝对可以为继承的属性赋予不同的值。如果您在采用该初始值的构造函数中初始化属性,然后传递与派生类不同的值,则可以执行此操作:

  • 我正在重写我的应用程序,它是在Objective-C到Swift。我想知道是否可以在新应用程序中使用以前应用程序中的一些旧的而不必在Swift中重写。有可能吗?