0

I've been learning Objective-C and just recently started using classes (instead of having everything in the ViewController). I'm running into a problem in that I don't know what to do with variables that I want to be accessible in other classes.

I have a NSArray of UIView that is created in my "ViewController". It is then passed to my "LayoutManager" that sets their frame based on the screen size. This array also needs to be accessed from my "BlockManager" and "ColorManager".

What is the best way to handle this array and other variables in similar cases. Should I use a global variable, and if so, how? Or is there a better way to do it?

jadengeller
  • 1,280
  • 1
  • 14
  • 25

2 Answers2

2

Global variables are generally a bad idea in object-oriented programming (the singleton pattern being possibly an acceptable exception, though opinions vary). In general you also want to avoid sharing raw data and letting anyone at all do whatever they want to it — you end up needing to give everyone internal implementation knowledge of everyone else and it becomes exceedingly difficult to manage.

In your case it sounds like LayoutManager is a one-shot task (or possibly once per rotation?), so it would be fine to phrase that object interaction as 'here are my views, please size them' and to make that the entire lifecycle of the object. So you'd pass the array to init, you'd let the class run once then you'd release it.

If BlockManager and ColorManager have something they need to communicate back to your view controller concerning its views, you should probably create suitable delegate protocols. Then the line of communication is that they let the view controller know whatever it is they've calculated it should know and it is responsible for taking action on the array.

Tommy
  • 97,164
  • 12
  • 174
  • 193
  • I hadn't thought of using delegates in that sense and leaving the array to the view controller. I'll try that out. I guess the class that is supposed to be managing everything in the view is the ViewController, so logically that does make sense. – jadengeller Feb 19 '12 at 23:56
2

It seems like you may be running into the problem of overusing Singletons for managing controllers that don't need to be Singletons. This may be useful:

I recently reworked my entire program from singleton to passing objects along as they're needed. Note that singleton and shared global objects are not identical, and Apple's own classes use sharedObject or defaultObject which instantiates and returns a shared instance, but nothing is stoping you from actually creating another instance of the class for your own needs.

Singleton on the other hand restricts the object to a single instance, and this means forgoing the ability to have two instances (which may be needed in the future) for the benefit of having complete access from anywhere. In that sense, you really only need the total access part and not the restriction of a single instance, so you might consider the sharedObject pattern. Here's an example:

// Up the top in the .m file
static MySharedClass *sharedInstance;

// A class method to return the shared instance
+ (MySharedClass *)sharedInstance {
    if (!sharedInstance) {
        sharedInstance = [[MySharedClass alloc] init];
    }
    return sharedInstance;
}

Having said that, I would consider structuring your program to pass objects as they are needed rather than setting up everything globally for access by everything. Otherwise the code you write with overuse of singleton/global objects is far more coupled and can't be pulled out of the current project and used elsewhere, and it makes debugging harder because you need to consider the global state of these manager classes.

I would create my main controller (ViewController) which will then instantiate the other controller classes needed and pass resources between them. This NSArray of UIViews you mention would be stored as high in the chain as is needed, presumably right up the top. This Presenter would then create the LayoutManager and pass the needed objects to it for further work. And in the same way, I would pass these objects to the BlockManager and ColorManager.

Community
  • 1
  • 1
Aram Kocharyan
  • 19,179
  • 11
  • 69
  • 93