views:

116

answers:

4

Please be nice.. I am a noob with this stuff. I want to allocate and use an object through a method that I call many times, and instead of making it a global variable and allocating it in my initWithFrame method I want to alloc it in just the one method, and make it a local variable that I allocate then and use then.

A: 

I'm not entirely sure I understand your question, but you can't really allocate the same object many times.

Each time you want a new instance, you ask the Class object to allocate a new instance for you (yes, classes being objects themselves is mind blowing). So this code:

NSString* s;
s = [[NSString alloc] init];
s = [[NSString alloc] init];

Here you are creating two instances of NSString. This code is bad because we have alloc'd the first instance and have not released, and assigned its only reference (s) to a new instance. This would cause a memory leak.

darren
A: 

If I understood your question correctly, you're looking for a static variable. A static variable keeps its value like a global variable, but it "lives inside" a function like a local variable. Your function could look something like this:

+ (MyObject *)getSingletonObject {
   static MyObject *obj = [[MyObject alloc] init];
   return obj;
}

obj would be created the first time you called this method, but calling the method again would return the same object it had already created.

Asher Dunn
That won't compile. Specifically, the compiler will error on the assignment expression because the RHS is not a constant expression and, thus, cannot be determined at compilation time.
bbum
Ahh, I'm used to C++ (where that would work as I stated). My mistake.
Asher Dunn
+4  A: 

You need to step back and think about how many different things need to access said object.

If it is everyone, then you should likely implement the shared instance pattern. Something like:

+ (MyObject *) mySharedObjectThatEveryoneUses
{
    static MyObject *sharedInstance;
    if (!sharedInstance) {
        sharedInstance = [MyObject alloc];
        sharedInstance = [sharedInstance init];
    }
    return sharedInstance;
}

Note that the above does not account for threading on initialization. I.e. if multiple threads simultaneously call the method for the first time, you might end up with multiple instances. Also note that the splitting of +alloc and -init is a pattern that is unique to this situation. Doing so avoids the situation where the -init method causes + mySharedObjectThatEveryoneUses to be invoked, creating a second instance before the assignment can happen.

Now, if you are talking about access within an object graph; access to the single instance within some subset of objects in your application, then you will need to have an instance variable somewhere that all of the objects can get to.

For example, say you are implementing a game where there is a Player object and that Player object has a bunch of Piece instances. When a Piece is created, you would typically have a property that refers to the owning player and that would be your single point of reference.

If you need something more transient, you should likely look to what should be your controller layer. I.e. there has to be some object somewhere that can act as a coordinator for the set of objects that need access to that single instance.

bbum
A: 

What you want is called a Singleton. You can read up on Apple's recommended way to create singletons here:

http://developer.apple.com/Mac/library/documentation/Cocoa/Conceptual/CocoaFundamentals/CocoaObjects/CocoaObjects.html#//apple_ref/doc/uid/TP40002974-CH4-SW32

Look for "Creating a Singleton Instance" in the "Cocoa Objects" section. There are a few more methods it's good to define beyond just a class level initializer.

Kendall Helmstetter Gelner