23

i got two swift files :

main.swift and view.swift

In main.swift i have a variable (Int) initially set to 0.

With an IBACtion I set that variable to be 10, and everything is ok.

However, if I try access that variable from view.swift, with a simple call like main().getValue(), i get always 0 and not 10 even if the variable has changed it's value in main.swift.

The method getValue() in main.swift looks like this:

func getValue() -> Int {
return variable
}

EDIT

Here is the code (Translated from Italian :D )

import Cocoa

class Main: NSObject {

    var variable: Int = 0

    func getValue() -> Int {
        return variable
    }

    @IBAction func updateVar(sender: AnyObject!) {
        variable = 10
    }
}

class View: NSView {
    override func drawRect(dirtyRect: NSRect) {
       println(Main().getValue()) //Returns always 0
    }
}

Thanks in advance Alberto

10
  • 1
    We need to see how variable is defined. Is it defined in a class or a struct? How are you trying to access the value in the other file?
    – drewag
    Commented Jun 20, 2014 at 18:06
  • It is defined in the class. I'm trying to access the variable in the other class just typing main().getValue()
    – Alberto
    Commented Jun 20, 2014 at 18:07
  • 3
    by typing main() you are creating a new instance of the main class with the default value (0) for variable
    – Jiaaro
    Commented Jun 20, 2014 at 18:09
  • 1
    There are so many unknowns with what you have told us so far. First, files don't really matter in swift. It is all about classes / structs and instances. Is main the name of your class (normally classes are capitalized)? Also, are you using a Xib file? It is strange to me that are using IBAction with a class called simply main. Normally it would be a subclass of a UIKit or Cocoa view or controller class.
    – drewag
    Commented Jun 20, 2014 at 18:10
  • yes, we'll need to see more code :) there's not enough to go on here
    – fqdn
    Commented Jun 20, 2014 at 18:11

2 Answers 2

44

I have solved this by creating a generic main class which is accessible to all views. Create an empty swift file, name it 'global.swift' and include it in your project:

global.swift:

class Main {
  var name:String
  init(name:String) {
    self.name = name
  }
}
var mainInstance = Main(name:"My Global Class")

You can now access this mainInstance from all your view controllers and the name will always be "My Global Class". Example from a viewController:

viewController:

override func viewDidLoad() {
        super.viewDidLoad()
        println("global class is " + mainInstance.name)
    }
12
  • 3
    Thank you. I have been wondering about this for 6 months (my entire swift career...) I have now learned how to store global variables accessible, settable and gettable, with modification from anywhere...!!!! ahhhh, thank you !!!
    – KML
    Commented Mar 27, 2015 at 14:23
  • 3
    This seems like a nice answer, but isn't one of our goals as programmers to refrain from using global variables? Commented Apr 1, 2016 at 21:24
  • 2
    Thank you very much for this!!!! Saved me all that trouble with using structs, NSUserDefaults, instances of classes etc etc!
    – Has
    Commented May 17, 2016 at 14:49
  • 2
    Thank you! saved me so much time and frustration :P Commented May 30, 2016 at 14:33
  • 2
    OMG thank you so much. You have no idea how relief I am now lol
    – nodyor90z
    Commented Dec 22, 2016 at 2:27
18

There is an important distinction to be made between "files" in Swift and "classes". Files do not have anything to do with classes. You can define 1000 classes in one file or 1 class in 1000 files (using extensions). Data is held in instances of classes, not in files themselves.

So now to the problem. By calling Main() you are creating a completely new instance of the Main class that has nothing to do with the instance that you have hooked up to your Xib file. That is why the value comes out as the default.

What you need to do, is find a way to get a reference to the same instance as the one in your Xib. Without knowing more of the architecture of your app, it is hard for me to make a suggestion as to do that.

One thought, is that you can add a reference to your Main instance in your Xib using an IBOutlet in your View. Then you can simply do self.main.getValue() and it will be called on the correct instance.

0

Not the answer you're looking for? Browse other questions tagged or ask your own question.