views:

269

answers:

5

I've had some experience developing for the iPhone but am entirely self taught and am trying to improve my practices. This is a question that is probably pretty introductory to programming.

What is the best way (or is it possible) to maintain instance variables with values that are common to all instances of an object? Is it possible to have the creation, modification, and checking of an object and its attributes happen in different places?

Say I have an object that keeps track of the number of times a user swipes the screen. Is it possible to, say, allocate that object in my AppDelegate, and then somehow increment the count variable of that object from different view controllers?

Is it possible to define an instance variable such that it is shared across all instances of the object to which it belongs? That would solve the problem.

So far, I've just made IVARs in my AppDelegate for the things like this that I've needed to keep track of and then just accessed them like this:

((MyAppDelegate *)[UIApplication sharedApplication].delegate).instanceVariable

but I don't know if that's a good practice or not. Probably not.

Maybe this is related to global variables or singletons. Or the prefix "shared" that appears above and I've seen in other places too. I'm just looking for advice or a direction to look. I hope this question makes sense and isn't too general.

A: 

I would look into using a singleton as a resource manager - maybe the resource manager part is not needed for you, but a singleton would greatly help you.

Mr-sk
+1  A: 

I think the question(s) you are asking involve different practices for different situations. To share data among viewcontrollers is one question with a number of solutions, one of the better ones being to use a delegate for all the viewcontrollers.

If you want to have a Class manage all its own objects, even if the objects come and go, you could do one of two things:

  1. Make the Class have a singleton, and keep track of allocations and deallocations in order to know when it should create and then dispose of itself (if needed). This is not a bad way to do it, although it may be more work.

  2. Create a controller class that manages your other class of objects. A good example may be a class of views, controlled by a viewcontroller class.

Let's see what other people suggest.

mahboudz
The problem with using a delegate approach is that as the number of view controllers grow, you have to keep passing along parameters, sometimes you are passing a value "through" several view controllers even though only the first and last view controller actually care about the value at all. It's for that reason I tend to prefer singletons to group like values, so that I can store and make use of values where they make the most sense in code and not have to pass stuff all over the place. I do prefer to make at least one singleton rather than stuff things in the AppDelegate.
Kendall Helmstetter Gelner
+1  A: 

In C++ or Java (etc), what you'd be looking for is a "static instance variable", which is exactly what you describe: an instance variable that is shared by all instances of the class. Objective-C does not have such a beast, precisely, but you can use some normal C syntax to give you something very similar.

See the bottom of this page: http://iphonedevelopertips.com/objective-c/java-developers-guide-to-static-variables-in-objective-c.html

(Copy of the code there in case the page vanishes:)

@interface MyClass 
{
  // ...
}
+ (NSString *)myVar;
+ (void)setMyVar:(NSString *)newVa;
@end

@implementation MyClass
static NSString *myVar;
+ (NSString *)myVar { return myVar; }
+ (void)setMyVar:(NSString *)newVar { myVar = newVar; }
@end

In this case "myVar" is global to the .m file, but because it's marked "static" (this is a C trick), the compiler limits its visibility to only the .m file that it's in. (As with anything like this, keep your eye on multithreaded access if you use that.)

FWIW, if you're building something that generally needs to be robust, a singleton-like object that everybody shares is a good way to go; you get all the normal Obj-C goodness (mem management if you want it) if you do that.

quixoto
+1  A: 

Matt Gallagher had post a great article on exactly that problem. You can see it at Cocoa with Love.

However, on a multiple view controllers patterns as mahboudz said, delegations is preferred.

gcamp
A: 

It is definitely bad practice to use keep everything in the app delegate and access it where needed.. at the very least it means code reuse becomes tricky. If you make a new app and want to use a view or control or part of the system, you'd have to also make sure your new app delegate implements all the right selectors and properties. Also, as your app grows you'll inevitably find your app delegate gets bigger and messier and harder to deal with.
Debugging becomes a pain too as it's harder to work out exactly which pieces of code are involved in a particular problem.

What I do this is to sketch out which parts of the app actually need which pieces of information, and pass those into the ViewControllers as they are created.

Ben Clayton