Swift:从另一个函数和/或类

时间:2018-04-23 15:48:31

标签: swift macos class variables

在Swift中尝试一些事情。我试图让一些看似混乱的东西理顺 - 主要是关于如何处理变量并在项目中引用它们。

我要做的是保持ViewController中定义的变量(基于结构)从应用程序中的各种其他函数访问和更新。

所以,我的代码的简要概述就在这里。在将它们应用到更复杂的东西之前,我实际上写了一个较小的应用程序来测试我的想法。

我在XCode中开始使用基于Swift文档的Mac OSX应用程序。

在ViewController.swift中我有:

import Cocoa
class ViewController: NSViewController {
    var myText = "Hello, some text"

    @IBOutlet weak var textView1: NSTextField!

    @IBAction func Button1(_ sender: Any) {
        myText = "This is button 1 clicked"
        myText = setText( thisText: &myText )
        textView1.stringValue = myText
    }

    @IBAction func Button2(_ sender: Any) {
        print("Button 2")
        myText = "This is button 2 clicked"
        textView1.stringValue = myText
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.   
        textView1.stringValue = myText
    }

    override func viewDidAppear() {
        let document = self.view.window?.windowController?.document as! Document
    }

    override var representedObject: Any? {
        didSet {
        // Update the view, if already loaded.
        }
    }
}

在SetText.swift中,我有这个:

import Foundation

func setText( thisText: inout String) -> String {
    thisText = "Function"
    return thisText
}

我喜欢将变量发送到Set Text函数然后返回它的想法,但更多地考虑它让我觉得实际上这最终可能会像一个众所周知的意大利面条,其功能调用函数并且知道还有什么。所以我认为这样的事情可能会更有意义:

import Foundation

func setText( thisText: inout String) {
    let vc = ViewController()
    // Read the variable from View Controller
    var myTextHere = vc.myText
    myTextHere = myTextHere + " More text"

    // Set the variable in ViewController here
    vc.myText = myTextHere
}

从我对这个主题的阅读,如果我调用ViewController(),它将创建一个新的视图实例(是正确的,还是我误读?)。这已经发生了,所以我需要的是引用调用函数setText的ViewController,或者更确切地说它拥有该特定的代码实例。当我在考虑基于文档的应用程序时,我显然希望将myText的所有实例与每个文档的ViewController保持在一起。

我的目标是创建一些更复杂的东西,使用基于Struct的变量来保持所有内容。所以:

myCard.image // holds a bitmap image
myCard.size // holds the size of the image

等等。能够以ViewController()的形式访问它.myCard读取和写入是我认为我需要做的。

我不想做的是使用全局变量。

感谢。

1 个答案:

答案 0 :(得分:0)

我很难看到问题标题与问题正文之间存在很多相关性。事实上,我甚至不确定是否有人提出问题。也就是说,我会尝试解决您似乎要问的问题(重写我认为他们的意图):

初始化新视图控制器时,是否会创建新视图?

是。每个视图控制器都有一个视图属性,它不是共享组件或单例或其他类似的东西。每个视图控制器都有一个主视图。它几乎可以肯定地由许多其他子视图组成,但是每个视图控制器都有一个 视图。

有没有办法从外部获取有关视图控制器状态的元数据,最好是以结构的形式?

绝对。首先,您需要定义Card结构。我建议在与视图控制器本身相同的文件中进行。您可以在视图控制器之外定义它,或者如果您想要更严格的耦合和命名空间,则可以在视图控制器中执行此操作。请注意,执行后者操作意味着类型名称在视图控制器外部引用时将为ViewController.Card,而不仅仅是Card

然后你想在视图控制器上创建一个计算属性(var card: Card)或一个方法(func card() -> Card),它根据状态构建并返回其中一个。听起来你已经倾向于采用房产方式了。

注意:我绝对建议不要使用正常的get / set属性,因为那时你必须不断更新并修改它。最好的办法是拥有一个计算属性,可以动态构建它。因此,当调用该属性时,它会进入所有组件以获取所需的信息(如图像大小,字符串等),然后打包并移交Card元数据结构。按需这样做可以消除不必要的复杂性,并将元数据逻辑整合到一个地方。

代码示例中的一些危险事项:

  • 我无法想出实施viewDidAppear()但不致电super.viewDidAppear()的充分理由。除非你有一个极其令人信服的理由将其遗漏(我真的不能想到一个), 这样做。
  • 我认为您首次实施setText(thisText:)方法没有任何充分理由。你在Button1(_ sender: Any) IBAction中使用它的方式在功能上绝对没有任何作用。这个方法通常有点麻烦,原因有以下几点:它有一个大写的方法名称,通过尝试分配给stringValue来设置textView文本有一些超级奇怪的原因,并且在三行中可以做到:

    textView1.text = "This is button 1 clicked"

  • setText(thisText:)的第二个实现比以前更没有意义。最大的两个问题是:1)你甚至没有使用传入的thisText参数,2)你的方法叫做'set text'是每次创建一个全新的视图控制器它被称为?这是对“在锡上做的事情”的严重违反。方法应该承担单一责任,不应该做任何超出该责任的事情。我不会在一百万年后看到一个名为setText的方法并且认为“我敢打赌这会初始化一个视图控制器。”从不。

我看到这个问题已经被忽略了(不是我),我想花一点时间指导你使用Stack Overflow:询问关于清晰,简洁,特定主题的清晰,简洁,具体的问题。正如我在答案的顶部所说,你的帖子中似乎没有任何问题。我不得不从你写的东西中推断出一些东西。

请记住:在您考虑应用时,编码不只是扭动您的手指。如果你正在做好工程的艰苦工作,你可能会花费大约10:1(或更多!)的比例盯着你的屏幕来实际输入任何代码。每次你写一行代码时,你应该问自己,“为什么我要编写这行代码?这有必要吗?我是否重新发明轮子?”

祝你好运!