0

I'm writing an iOS app where there is a common object that all views within the app need to access.

I have been creating, and initialising the object within the viewDidLoad event (of the first view controller), and then passing a reference to this object to all other views that need it. This does not seem like the correct way to do things, feels like I'm somehow breaking the MVC pattern since I'm relying that this particular view is always the first to load in order to setup objects that the whole application needs.

I have now modified my app to do the basic object creation and initialisation in the appDelegate "didFinishLaunching...". This is now working and I can access this common object from all of my other views without having to pass around a reference from one view to the other.

Before I go and continue too far, I was hoping to get peoples input on whether this is the correct way to do things, or whether I should be doing anything else? Sorry if this seems like a trivial question, I'm just learning and want to learn how to do things properly.

Thanks in advance :-)

Sabur Aziz
  • 236
  • 1
  • 2
  • 9

2 Answers2

1

Putting your global object initialisation in didFinishLaunching is a better idea than having it in didLoad.

Some people will disagree with me here and say you shouldn't have globals full stop, but personally I think having some sort of global state is acceptable. I love a good object-orientated app but there is a balance to be struck between solid OOP and the flexibility provided by having a few globals.

I think ultimately do whatever is right for you, the major disadvantage of having a global state is that it becomes difficult to maintain and has the potential to introduce a lot of bugs / unexpected behaviour especially in a large app, whereas if you stick to the MVC pattern then each view in your app simply does what it is meant to without unnecessarily affecting other parts of the app.

Nowadays, I tend to stick to MVC / OOP principles for the most part, but have an [AppDelegate]sharedAppDelegate] singleton I can use to access variables at certain points. I have very, very few variables in here but they do come in handy i.e. now my app has a shared 'loading HUD' which is managed by this class, and my sharedAppDelegate also contains a lot of static methods for initiating HTTP, parsing JSON etc which saves a lot of time.

One alternative to having global information in your appDelegate is using NSUserDefaults to store key-value information

Hope that helps anyway, like I said some people will disagree with me but ultimately it boils down to personal preferences, and where the balance for you in terms of rigidity to the MVC model versus flexibility is

James Gupta
  • 871
  • 7
  • 15
  • Thanks for your answer, it makes me feel a bit better about what I am doing. I totally agree with you, sometimes its handy to have a "common object" (i've tried to avoid the use of the word: global) that needs to be accessed by other views. I feel that this way is more in the spirit of the MVC pattern since the object is more loosely coupled to the workings of the app. This way, I theoretically should be able to change the firstviewcontroller without having to add the object creation and init code into the new firstviewcontroller. – Sabur Aziz Jul 14 '13 at 08:38
1

Without repeating what has already been answered, I'd suggest you make your own Singleton object to hold your 'globals', so you don't clutter your AppDelegate with it.

@interface MyGlobalDataController : NSObject

@property (nonatomic, strong) MyData *myData;

+(MyGlobalDataController *)sharedInstance;

@end

@implementation MyGlobalDataController

static MyGlobalDataController *MyGlobalDataControllerSharedInstance = nil;

- (id)init {
    self = [super init];
    if (self) {
        // do whatever needs doing 
    }
    return self;
}

+(MyGlobalDataController *)sharedInstance {
    @synchronized(self) {
        if (MyGlobalDataControllerSharedInstance == nil) {
            MyGlobalDataControllerSharedInstance = [[MyGlobalDataController alloc] init];
        }
    }
    return MyGlobalDataControllerSharedInstance;
}

@end

The first time you access your sharedInstance, the init will be called, so you don't have to worry about timing there.

schmubob
  • 301
  • 2
  • 6
  • Ok, this is cool :-) got my singleton up and working and it works just as I need it. Thanks again for everyones help. – Sabur Aziz Jul 14 '13 at 09:21