1

It's a classic problem.

I would like to access an array of objects from anywhere within my app. I would also like to do this using a singleton. My questions are:

  1. Where do I instantiate my singleton object?
  2. Where do I instantiate my NSMutable array of objects?
  3. How do I refer to this array from anywhere within my project?

All code and examples are greatly appreciated!

EDIT 1

This is what I have so far. I can't figure out though how to access this array of bananas correctly and consistently:

#import <Foundation/Foundation.h>

@interface Singleton : NSObject {
    NSMutableArray *bananas;
}

@property (nonatomic, retain) NSMutableArray *bananas;

@end


#import "Singleton.h"

static Singleton *mySingleton;

@implementation Singleton

@synthesize bananas;

#pragma mark SingletonDescption stuff

+ (Singleton *)mySingleton
{
    if(!mySingleton){
        mySingleton = [[Singleton alloc]init];
    }

    return mySingleton;
}

+ (id)allocWithZone:(NSZone *)zone
{
    if (!mySingleton) {
        mySingleton = [super allocWithZone:zone];
        return mySingleton;
    } else {
        return nil;
    }
}

- (id)copyWithZone:(NSZone*) zone
{
    return self;
}

- (void)release
{
    // NO OP
}

@end

EDIT 2

This is how I'm trying to use my singleton object to have an array of objects placed in a table cell. Nothing is happening and the table cell comes up blank :(

- (id)init
{
    [super initWithStyle:UITableViewStylePlain];

    // bananas = [[NSMutableArray alloc] init];

    Singleton *mySingleton = [[Singleton alloc]init];
    mySingleton.bananas = [[NSMutableArray alloc]init];

    UIImage *imageA = [UIImage imageNamed:@"A.png"];
    UIImage *imageB = [UIImage imageNamed:@"B.png"];
    UIImage *imageC = [UIImage imageNamed:@"C.png"];

    Banana *yellowBanana = [[Banana alloc] initWithName:@"Yellow" description:@"Beautiful" weight:22.0 icon:imageA];
    Banana *greenBanana =  [[Banana alloc] initWithName:@"Green" description:@"Gorgeous" weight:12.0 icon:imageB];
    Banana *rottenBanana = [[Banana alloc] initWithName:@"Rotten" description:@"Ugly" weight:8.0 icon:imageC];

    [mySingleton.bananas addObject:yellowBanana];
    [mySingleton.bananas addObject:greenBanana];
    [mySingleton.bananas addObject:rottenBanana];
}
Atulkumar V. Jain
  • 5,102
  • 9
  • 44
  • 61
Eric Brotto
  • 53,471
  • 32
  • 129
  • 174

2 Answers2

10

Do your singleton like this:

@interface Singleton : NSObject
@property (nonatomic, retain) NSMutableArray *bananas;
+(Singleton*)singleton;
@end
@implementation Singleton
@synthesize bananas;
+(Singleton *)singleton {
    static dispatch_once_t pred;
    static Singleton *shared = nil;
    dispatch_once(&pred, ^{
        shared = [[Singleton alloc] init];
        shared.bananas = [[NSMutableArray alloc]init];
    });
    return shared;
}
@end

The singleton is initialized the first time you use it. You can call it from anywhere at any time:

NSLog(@"%@",[Singleton singleton].bananas);
Jano
  • 62,815
  • 21
  • 164
  • 192
2
  1. You use lazy instantiation, that is, a class method that returns your singleton object. The first time this method is called, it creates the instance, all other times thereafter, it just returns the already available instance (retained in a class variable).

  2. I thought the point of your singleton was to hold this array? You could either create it in the singleton's initializer, or create it lazily when it is needed the first time.

  3. In your AppName-pefix.pch file, you #import its class. This global import will be available in your whole application.

fzwo
  • 9,842
  • 3
  • 37
  • 57
  • This seems like a good start, but I'm still a bit unclear on the syntax. Could you take a look at the code I've just posted and maybe point out how I would call on the array? Thanks :) – Eric Brotto Jun 12 '11 at 21:40
  • @Eric Brotto I'm afraid I don't understand your problem, or what finer points there would be. It seems you have the singleton-generation-thing going pretty well. – fzwo Jun 12 '11 at 21:44
  • @Eric Brotto In your `mySingleton` method, make sure to initialize the array. Or write your own getter for the array instead of synthesizing it, wherein you could lazily create the array. – fzwo Jun 12 '11 at 21:47
  • @fzwo, I'm trying to initialise the array by using self.bananas = [[NSMutableArray alloc]init], but no such luck. My apologies if I'm asking for you to spell it out for me :( – Eric Brotto Jun 12 '11 at 21:59
  • @Eric Brotto I don't see why that should fail. Your *are* doing this on the instance, not the class, right? – fzwo Jun 12 '11 at 22:05
  • @fzwo. Thanks for your perseverance. I've posted a second Edit to show how I'm trying to use it. – Eric Brotto Jun 12 '11 at 22:17
  • @Eric Brotto if this is a singleton, you should IMHO not expose its array directly. Instead, in the singleton's `init` method, initialize the array, and provide getters and Setters for Bananas: `- (void)addBanana:(Banana *)banana`. – fzwo Jun 12 '11 at 22:21
  • 2
    @Eric Brotto Also, you're not using your singleton as a singleton! Use `Singleton *mySingleton = [Singleton mySingleton]`. And think of better class and method names! How about calling your singleton class `BananaBunch`, its singleton-getter `defaultBunch`, or something to that effect? Your code would then read: `BananaBunch *myBunch = [BananaBunch defaultBunch]; [myBunch addBanana:yellowBanana];` – fzwo Jun 12 '11 at 22:26
  • Man, still not happening. On the Singleton *mySingleton = [Singleton mySingleton] line I'm getting the warning 'Method +mySingleton not found (return type defaults to 'id'. It runs, but I'm not seeing my bananas in the table cell. Thanks so so much :) – Eric Brotto Jun 12 '11 at 22:40
  • You probably haven't declared the method in the header file. You should really learn the basics. Let me recommend a good book: [IPhone Programming: The Big Nerd Ranch Guide](http://www.amazon.com/IPhone-Programming-Ranch-Guide-Guides/dp/0321706242/) – fzwo Jun 12 '11 at 22:52
  • Ha ha. That's actually where I got the sample code from! But, you are right. I have a lot to learn. Thanks for the help though! I've solved it with @Jano's answer. – Eric Brotto Jun 12 '11 at 22:58
  • That book is IMHO very good as a learning book, but it won't shine if you're just using it to look stuff up. It's quite obvious that you're lacking the basics; just work through the book from the first chapter, and it'll be easy. Won't even take long. – fzwo Jun 12 '11 at 23:02