Access variable in different class - Swift

61,484

Solution 1

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.

Solution 2

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)
    }
Share:
61,484

Related videos on Youtube

Alberto
Author by

Alberto

AI Product Dev @casavo. Ex-Founder @ Neuraly. Machine Learning & Deep Learning with focus in Natural Language Processing. UIC Chicago & Politecnico di Milano

Updated on March 07, 2020

Comments

  • Alberto
    Alberto about 4 years

    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

    • drewag
      drewag almost 10 years
      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?
    • Alberto
      Alberto almost 10 years
      It is defined in the class. I'm trying to access the variable in the other class just typing main().getValue()
    • Jiaaro
      Jiaaro almost 10 years
      by typing main() you are creating a new instance of the main class with the default value (0) for variable
    • drewag
      drewag almost 10 years
      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.
    • fqdn
      fqdn almost 10 years
      yes, we'll need to see more code :) there's not enough to go on here
    • fqdn
      fqdn almost 10 years
      yep, I believe Jiaaro's comment takes it! good guess!
    • Alberto
      Alberto almost 10 years
      Of course I am using XIB file.. Everything is linked and yes , class names are Capitalized. I'm italian and therefore i changed the names to make it easy for you to help me, sorry for the mess
    • Alberto
      Alberto almost 10 years
      Jiaaro, I imagined that, but then , how to access that var ? I need it inside a drawrect method and should be updated by the user, so via IBAction
    • drewag
      drewag almost 10 years
      @FoxNos I completely sympathize with your need to translate your code for us to help you and I don't blame you at all :). I am just trying to help you to create a question that we can answer confidently and also a question where other people might benefit from the answer.
    • Alberto
      Alberto almost 10 years
      It's hard to me to explain, but the task is very easy i think. I got two files, not class, made pressing CMD+N. I gave them 2 different names. One is a subclass of NSObject and the other is a subclass of NSView. In one file i want to control IBactions and user-stuff, in the other I want to make changes to a view using BezierPath. However, if the user changes some parameters of drawing, saved in main file (Subclass of NSObject, as I said), I will then need to access in the DrawRect method. Enough clear ? Thanks a lot, really :)
  • RanLearns
    RanLearns about 9 years
    This was exactly what I needed. Thanks!
  • KML
    KML about 9 years
    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 !!!
  • jeffery_the_wind
    jeffery_the_wind about 8 years
    This seems like a nice answer, but isn't one of our goals as programmers to refrain from using global variables?
  • Kokodoko
    Kokodoko about 8 years
    Yes, but it's almost always just very handy to have a single "manager" class that everyone can access. There are many ways to achieve this, you could also pass a reference to your manager class around as a function argument - but I find that messy.
  • Has
    Has almost 8 years
    Thank you very much for this!!!! Saved me all that trouble with using structs, NSUserDefaults, instances of classes etc etc!
  • kishorer747
    kishorer747 almost 8 years
    Thank you! saved me so much time and frustration :P
  • nodyor90z
    nodyor90z over 7 years
    OMG thank you so much. You have no idea how relief I am now lol
  • Ivan Cantarino
    Ivan Cantarino almost 7 years
    What about a singleton.?
  • S At
    S At over 6 years
    Can with this approach change mainInstance ?
  • Cobie Fisher
    Cobie Fisher over 6 years
    If you needed to change the name in mainInstance from another ViewController, how would you go about doing that?
  • Robbie
    Robbie over 4 years
    how would I make the whole instance of Main accessible? So that I can call functions within the Main instance...
  • Kokodoko
    Kokodoko over 4 years
    Perhaps you could make Main a Singleton! Then Main would be accessible anywhere using Main.getInstance()
  • Talha Shahab
    Talha Shahab over 3 years
    Well done! Global instance of the class should be the ultimate solution'