How do you deal with singleton objects in your app? - iphone

The first approach that comes to my mind is to put the singleton object in the appDelegate object as property. In this way you can access it from anywhere using
#import "myAppDelegate.h"
// ...
[[(myAppDelegate *)[UIApplication sharedApplication] delegate] SingletonObj]
The downside is you have to explicitly cast and import the header of your delegate to tell the class you're working with that SingletonObj is actually a property of the delegate. And I think this makes the code smell a little.
The second approach is to create a legit singleton class. This, however, require more work. And I personally think that one Singleton class, is more than enough.
I'm not a programmer so I would greatly appreciate corrections on my reasoning, and opinions on the subject.

Singletons are most often handled in a class via a method like +sharedInstance.
Here is a good write-up.

I found a xcode template for easy singleton generation on the net.

Best practice is to only ever put UIApplicationDelegate-related things in your AppDelegate class. Evarr.
Decide if you really need a singleton. If you do, just make a legit singleton class. It will be easier in the long run; did you notice how long it took to type that monster of a line, where you tried to get the singleton object out of the AppDelegate? Agh.
(Also, just a little bit of idiom: classes start with a capital letter, and methods start with a lowercase letter; hence, you problem meant [[(MyAppDelegate *)[UIApplication sharedApplication] delegate] singletonObj].)

Related

Using #DEFINE to share Managed Object Context

Just looking for a little feedback on if this is a bad idea for sharing the Managed Object Context.
In the MyApp-Prefix.pch file I have added following:
#import "AppDelegate.h"
#define MOC [(AppDelegate*)[UIApplication sharedApplication].delegate managedObjectContext]
Then when I need to access the context I do the following (just an example):
[MOC deleteObject:[self.fetchedResultsController objectAtIndexPath:indexPath]];
This seems to work great, but it also seems too easy, especially since I don't see it mentioned anywhere. Is this a bad design pattern?
Thanks for any feedback
Instead of a compiler macro (which can cause surprises sometimes) I usually define a class method on my app delegate, like this:
+ (AppDelegate *)sharedDelegate
{
return [[UIApplication sharedApplication] delegate];
}
Then, when I need a reference to some global state, I can call it like this:
[[[AppDelegate sharedDelegate] managedObjectContext] deleteObject:foo];
If your app is complex enough, it might be worth the trouble of passing around a reference to a managed object context, rather than using a global one. If you do, it becomes easier to refactor and use other techniques later, like child contexts to group changes.
To be specific, that means each view controller has it's own managedObjectContext instance variable. When you present a new view controller, you pass along a reference: maybe in a custom init method, maybe by setting a property. None of your classes (except maybe the root view controller) ever reference your global app delegate. This way, if you had a complicated editing view, you could give it a child context where it could save changes "temporarily" (to verify that all the objects are valid); if the user hits the cancel button, you just throw the whole context away.
Also, if you're always using the global context, you might have bugs that are hard to track down. For example, an edit view that doesn't clean up after itself leaves an invalid object behind. Then the next time you go to save something unrelated, you get an error! Happened to me, was no fun to debug.
Nothing wrong with that approach — but unless the delegate's managed object context is going to change during your program's lifetime, it seems more sensible and efficient to use a global variable. The Cocoa AppKit framework takes the second approach with with the NSApp variable, which is set to [NSApplication sharedApplication].

Using #define to access App Delegate Object doesn't work

I am using App Delegate object in different classes. I want access it in whole project. Am define this object in Prefix.pch file as
#define Appdelegate (AppDelegate *)[[UIApplication sharedApplication] delegate]
but problem is that Appdelegate variable does not access App delegate variable.
it Shows error.
but if am use this code works fine
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
appDelegate.variablename;
Am I doing it correct or is there a way of doing what I do?
thanks in Advance.
Should be:
#define Appdelegate ((AppDelegate *)[[UIApplication sharedApplication] delegate])
// ^----------------------parenthesis--------------------------^
As this question and its answers demonstrate, leaning on the preprocessor is usually a bad idea.
It's easy to get things wrong. We all develop good instincts for operator precedence, but the preprocessor has no clue. To defend against unexpected context problems, you often need to wrap everything in extra parens and braces.
It's easy to convince yourself that you're doing one thing when the code is doing another. When things break, neither the compiler's error messages nor the debugger are likely to help much.
Most important, the preprocessor can let you take a bad idea and spread it pervasively through the program. The bad idea here is using the App Delegate globally.
Global variables are a code smell. Efforts to make global variables even more global by stuffing them into precompiled headers are a code smell. If the framework thought you should have access to the AppDelegate from everywhere, you wouldn't need to jump through these (modest) hoops!
So, when tempted to do something like this, it's nice to know the preprocessor is there and the pch headers are there, but keep in mind that you're fighting the framework and almost certainly making a design error. That might be OK in your context, but it's something to know.
You need to import AppDelegate file where you are declare delegate macro:
#import "AppDelegate.h"
And then define
#define Appdelegate (((AppDelegate *)[[UIApplication sharedApplication] delegate]))

Main AppDelegate

Sorry for questioning so dummy question, but I swear I used Google before doing it :)
So, the question is - how do I set the main AppDelegate class for my application? I mean, if I don't want to use the one generated by Xcode but to work with my own class for that.
I'm newbie in iOS programming, so probably I misunderstood some part of theory.
I will highly appreciate any of your help!
I can't imagine why you would want to reset the app delegate that your template sets up for you, but to it you'd take a .h interface and have it conform to the <UIApplicationDelegate> protocol, alloc & init that object (for the sake of arguments, we'd call it yourNewlyCreatedDelegateInstance) and then you could set your app delegate to that via [[UIApplication sharedApplication] setDelegate: yourNewlyCreatedDelegateInstance].

Macros for appdelegate access using multiple targets

I was reading a post on accessing the app delegate using shorthand with a macro here
Short hand for [[UIApplication sharedApplication] delegate]?.
The solution to the problem provided was to define the following macro in the app delegate header.
#define AppDelegate (YourAppDelegate *)[[UIApplication sharedApplication] delegate]
My question is how can I do this with a project that has multiple targets seeing as the appdelegate name would be different for each one?
T he #define macro is just a string substitution facility in the pre-processor, so I don't think there is much you can do short of defining another macro that has the name for each target's app delegate.
The savings in typing to abbreviate the app delegate is not going to be very much, and imo probably not worth the time to do it.
And I will editorialize further to say that if you're making enough references to your app delegate to justify abbreviating, I think you need to move some code out of the appDelegate into better factored (possibly singleton) classes. My 2 cents.

Best Application Delegate Practice

I have been making a few apps here and there, and I know my way around. What has always confused me is accessing global attributes, and where the best place to set them are. I have a few questions about accessing things and how to access them.
Do you have to include your application delegates header file into any other other file you want to access it in? Say I have a view controller, that I would like to use, do I need to include the .h inside my view controller's .h? Or can I set the:
#class AppDelegate;
Can you only access the delegate by typing out:
[UIApplication sharedApplication].delegate
EACH and every time? Is that something I just have to get used to? Or could I set the following in my implementation in each .h:
AppDelegate *delegate;
And inside the init function, put the singleton instance to that variable?
Sorry if this was off structure, but I think it's a logical question people have a problem encountering and solving.
Maybe you need to reconsider how you are using the App Delegate? It sounds to me like perhaps you are not making a very good class design.
Regardless, here's a way to make it easy. Don't put this in init just use it when you need it.
MyAppDelegate *delegate = (MyAppDelegate *)[[UIApplication sharedApplication] delegate];
Naturally, replace MyAppDelegate with the actual class name of your app delegate.
Another possibility is to add the code to use a properly casted app delegate reference as a #define in the app delegate header file, so after including it you can do something like:
MYAPPDELEGATE.customProperty = blah;
However I tend to favor just writing out the line that John presented, as use of #defines confuses code completion which I find more annoying than just typing the line.
As also mentioned, if you have a ton of references to the app delegate you may want to restructure to keep some of those references closer to home.