除非您是 Apple,否则“扩展程序可能不包含存储的属性”?我错过了什么?

Ber*_*gdu 6 xcode swift swift4 xcode9

苹果怎么能做到这一点:

import CoreGraphics
import GameplayKit
import simd

/**
 @header


 SceneKit framework category additions related to GameplayKit integration.


 @copyright 2017 Apple, Inc. All rights reserve.

 */

extension SCNNode {


    /**
     * The GKEntity associated with the node via a GKSCNNodeComponent.
     *
     * @see GKEntity
     */
    @available(OSX 10.13, *)
    weak open var entity: GKEntity?
}

/**
 * Adds conformance to GKSceneRootNodeType for usage as rootNode of GKScene 
 */
extension SCNScene : GKSceneRootNodeType {
}
Run Code Online (Sandbox Code Playgroud)

......我不能这样做:

extension SCNNode {
    weak open var ntity: GKEntity?
}
Run Code Online (Sandbox Code Playgroud)

并得到两个错误:

  • 'weak' 可能只适用于类和类绑定的协议类型,而不适用于 '<<error type>>'
  • 扩展可能不包含存储的属性

我实际上想做的是在 10.13 之前的 OSX 版本上提供实体属性,因此也欢迎对此提出其他建议。

dre*_*ter 12

斯威夫特 4 / iOS 11 / Xcode 9.2

这里的答案在技术上是正确的,但无论如何这里有一个解决方案。

在您的扩展中,使用您想要的字段定义一个私有结构。使一切静态,像这样:

private struct theAnswer {
    static var name: String = ""
}
Run Code Online (Sandbox Code Playgroud)

我知道,我知道,静态意味着它是一个类范围的变量/属性,而不是一个实例变量/属性。但是我们实际上并不打算在这个结构中存储任何东西。

在下面的代码中,obj_getAssociatedObjectobjc_setAssociatedObject都需要一个UnsafeRawPointer作为键。我们使用这些函数来存储与此唯一实例关联的键/值对。

这是带有字符串的完整示例:

import Foundation

class ExtensionPropertyExample {

    // whatever
}


extension ExtensionPropertyExample {
    private struct theAnswer {
        static var name: String = ""
    }

    var name: String {
        get {
            guard let theName = objc_getAssociatedObject(self, &theAnswer.name) as? String else {
                return ""
            }
            return theName
        }
        set {
            objc_setAssociatedObject(self, &theAnswer.name, newValue, .OBJC_ASSOCIATION_RETAIN)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


Kai*_*rdt 5

这在 Swift 中目前是不可能的。正如 Sulthan 所指出的,这是一个 Objective-C 类别,您可以看到它的 Swift 版本,它是由 Xcode 生成的。

现在,Objective-C 并不容易支持在类别中添加属性(扩展在 Objective-C 中称为类别),但是您可以使用关联的对象来获得您想要的。

Mattt Thompson 在他的 NSHipster 博客上有一篇关于关联对象的精彩文章:关联对象 - NSHipster