【问题标题】:How to use foreign variables in classes如何在类中使用外部变量
【发布时间】:2017-05-26 11:40:16
【问题描述】:

我有两个 .swift 文件,因此我希望其中一个文件修改另一个类的 IBoutlet 标签的文本。

第 1 类:

class class1: UIViewController {

    @IBOutlet var label1: UILabel!
}

第 2 类:

class class2: SKScene {
    var cool_variable = 1

    func coolFunc () {

        class1.label1.text = "\(cool_variable)"
    }
}

通过这样做,我收到以下错误消息: 实例成员“label1”不能用于类型“class2”

提前致谢!

【问题讨论】:

  • 你当然可以这样做。但是,我们可能需要更多信息来帮助您,您能用更多代码更新您的帖子吗?
  • 当然!给我2分钟!
  • 您需要访问该类的运行实例。您的课程单独运行。因此,如果您需要从另一个更改另一个的信息,您应该使两个类都可以访问的全局可访问变量。如果可以这样做,则可以更新标签: self.label1.text = globalVariable
  • @YoamFarges 完成!
  • 做与原始代码相同的事情在 ObjC 中也不起作用。

标签: ios swift xcode class swift3


【解决方案1】:

类和实例之间的区别和关系对于面向对象编程绝对至关重要。因此,请考虑您提出的代码:

func coolFunc () {
    class1.label1.text = "\(cool_variable)"
}

这里的问题是class1 是一个 的名称。 (如果您只是遵循类名以大写字母开头的基本规则,那将更加明显。)但是label1 是一个实例属性。因此,这里需要的是class1 类的instance 的名称——大概是对已经是视图层次结构一部分的实际现有实例的引用。

【讨论】:

    【解决方案2】:

    您永远不会在class2 中创建class1 的实例来访问变量。

    我猜你正在使用 Storyboards。在这种情况下,您不想创建class1 的实例。相反,您将使用委托(如果您不使用 Storyboard,这也是一个好主意)。

    委派可能是一个复杂的话题,所以我会尽量保持简单。

    首先,您从协议开始。通常你把它命名为<CLASS-NAME>DataSource,所以你会这样做:

    protocol class2DataSource: class {}
    

    委派协议需要class 关键字。

    然后,当您调用协议委托的类中的方法时,您可以将希望在其他类中调用的方法添加到其中,例如,willCoolFunc

    protocol class2DataSource: class {
        func willCoolFunc(with variable: Int)
    }
    

    您拥有该参数,因此您可以尝试访问变量cool_variable

    接下来,您需要在class2 中创建一个class2DataSource 类型的变量:

    weak var dataSource: class2DataSource?
    

    确保变量是weak 并且是可选的。

    接下来,调用方法,你会在coolFunc

    func coolFunc () {
        dataSource?.willCoolFunc(with: cool_variable)
    }
    

    现在你,要在调用函数时访问cool_variable,你需要在class1上实现class2DataSource。创建实现class2DataSourceclass1的扩展并添加函数willCoolFunc

    extension class1: class2DataSource {
        func willCoolFunc(with variable: Int) {
    
        }
    }
    

    现在您可以在class1 中访问变量cool_variable!原因是因为当你调用class2.coolFunc()时,willCoolFunc方法被传入cool_variable。任何实现class2DataSource的类都可以通过willCoolFunc方法访问cool_variable

    为了完成该方法,扩展程序如下所示:

    extension class1: class2DataSource {
        func willCoolFunc(with variable: Int) {
            self.label1.text = "\(variable)"
        }
    }
    

    我们差不多完成了,但还没有完成。我们仍然需要将class1 设置为class2DataSource 的数据源。为此,我将从this post 引用 Nikolay Mamaev:

    1. 转到界面生成器。

    2. 在对象库的搜索文本字段中键入“对象”,然后将“对象”拖到包含连接到的视图控制器中 class1(即,与添加任何视图或视图控制器相同) 故事板场景,除了您添加的不是视图或视图 控制器而是一个抽象对象)。

    3. 在故事板左侧的“场景”面板中,突出显示刚刚添加的对象;在右侧面板中转到“身份检查器”和 键入 class2DataSource 而不是预定义的 NSObject。在左侧 panel ('Scenes'), 'Object' 将被重命名为 'Class2 Data Source' 自动。

    4. 在情节提要左侧的“场景”面板中,从 UIView [*不是控制器*] 控制并拖动到“Class2 数据源”; 在弹出窗口中,选择dataSource outlet。

    那里!现在,当您调用class2.coolFunc() 时,您将class1label1 的文本设置为cool_variable 的值!

    【讨论】:

      【解决方案3】:

      我不知道您要解决的确切问题,但我将考虑您要在class1 中访问class2 中的变量的部分。有两种基本方法可以解决这个问题,一种是继承,另一种是创建对象。这些是您需要熟悉的基本面向对象编程概念。

      Swift 不支持多重继承。所以排除了继承来解决你的问题,因为你继承了两个类SKSceneUIViewController

      class1中创建一个对象并调用函数coolFunc

      class class1: UIViewController {
          @IBOutlet var label1: UILabel!
          func modifyLabel(){
              let someObject = class2()
              someObject.coolFunc()
          }
      }
      

      当然,此解决方案可能不是您正在寻找的解决方案。如果您需要一个适合您的解决方案,您将不得不更多地解释您所面临的问题。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-12-25
        • 1970-01-01
        • 1970-01-01
        • 2014-02-09
        • 2023-01-19
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多