在单独的 .swift 文件中使用扩展名

Posted

技术标签:

【中文标题】在单独的 .swift 文件中使用扩展名【英文标题】:Using extensions in separate .swift file 【发布时间】:2014-06-10 05:11:12 【问题描述】:

寻找在单独文件中使用 Swift 扩展的方法或替代解决方案。仅当将扩展名写入正在使用的同一文件中时,才能创建扩展名。

这是一个有效的 ViewController.swift 示例。

import UIKit
var TestHelper: String = "Start Value"
extension UIView 
var testValue:String
set
    TestHelper = newValue

get
    return  TestHelper




class ViewController: UIViewController 
override func viewDidLoad() 
    super.viewDidLoad()
    self.view.testValue = "Some Value"

override func didReceiveMemoryWarning() 
    super.didReceiveMemoryWarning()


从这个文件中取出扩展名并放入一个新文件会导致崩溃并给出以下错误:

Program ended with exit code: 9

这个错误是说我认为它不存在。在需要扩展的每个单独文件中创建扩展显然会产生无效重新声明的问题。

提前致谢!

【问题讨论】:

当我尝试这个时,编译器崩溃了。你可能想file a bug。 我对扩展内部的属性感到非常不确定。没有***.com/a/24115223/1726069的情况吗? 【参考方案1】:

如果您将扩展名移动到另一个文件,那么您也必须移动 TestHelper。或者更简单:将 TestHelper 放入扩展中

【讨论】:

我应该澄清一下我已将扩展帮助程序放在扩展文件中。似乎无所谓。如果我没记错的话 testHelper 放在扩展程序中需要使用 getter/setter 并导致通过将它放在外面解决的相同问题?【参考方案2】:

我尝试了这个问题,认为这很容易,但它似乎比我最初想象的要复杂。

我最终不得不继承 UIView。我无法为添加了 var 的 UIView 创建扩展。我想也许他们强迫我们继承 UIView,因为 init 或 get/set 是如何为类工作的。我刚做了这个。它不一样,但具有相同的功能

import UIKit

class MyView: UIView 
    var testValue: String?
    init(frame: CGRect) 
        super.init(frame: frame)
        self.backgroundColor = UIColor.greenColor()
        self.bringSubviewToFront(self.superview)
    

然后就这样使用它

override func viewDidLoad() 
    super.viewDidLoad()

    let myRect = self.myContent.frame
    let myNewView: MyView = MyView(frame: myRect)
    myNewView.testValue = "has been set"
    self.myView.addSubview(myNewView)

    NSLog("%@", myNewView.testValue!)


我可以用 var 扩展数组

extension Array 
    var last: T? 
    if self.isEmpty 
        NSLog("array crash error - please fix")
        return self [0]
    
    else 
        return self[self.endIndex - 1]
        
    

如果只添加函数而不添加变量,很容易为 UIKit 创建扩展

extension UIView 
    func layerborders() 
        let layer = self.layer
        let frame = self.frame
        let myColor = self.backgroundColor
        layer.borderColor = UIColor.whiteColor().CGColor
        layer.borderWidth = 0.8
        layer.cornerRadius = frame.width / MyConstants.CornerRadius.toRaw()
    

【讨论】:

感谢您抽出宝贵时间检查此问题。我喜欢这个解决方案,但遗憾的是它可能不会是我用作解决方案的东西。我觉得使用它来设置标签栏或导航栏的样式会导致分层问题和覆盖按钮等。【参考方案3】:

我也遇到了同样的错误并试图解决它我发现在扩展变量声明前面添加 static 似乎可以解决问题:

import UIKit

static var TestHelper: String = "Start Value"

extension UIView 

    static var testValue: String 
        set 
            TestHelper = newValue
        
        get
            return  TestHelper
        
    



class ViewController: UIViewController 

    override func viewDidLoad() 
        super.viewDidLoad()
        self.view.testValue = "Some Value"
    

    override func didReceiveMemoryWarning() 
        super.didReceiveMemoryWarning()
    


希望对你有帮助!

【讨论】:

【参考方案4】:

“扩展无法添加存储属性”(来自"The Swift Programming Language")

【讨论】:

以上是关于在单独的 .swift 文件中使用扩展名的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Swift 中从文件扩展名中拆分文件名?

在位于 XCTestCase 的单独文件中的函数中捕获屏幕截图

在 Swift 中导入扩展文件

在 Swift 中使用 Objective-C 扩展类

在 Swift 4.2 Xcode 10 中使用动作扩展从 Safari 共享 PDF 文件失败

播放存储在谷歌驱动器中的音频文件(远程 URL) - Swift