Public scope in Objective-C?

iphone, objective-c

Solution

I make properties available to all views managed by a Tab Bar via a singleton representing my data model. This is efficient and allows all Views access to the data (as well as any other application elements. Creating the singleton is straightforward (there are a ton of examples on S.O.). The you just request the instance and get the property values you need.

Here is a framework fro creating the Singleton. The key points are the static instance and the fact that you do the initialization as `[[self alloc] init];`. This will ensure the object gets cleaned up correctly. All the methods at the bottom of the class are standard from the SDK Docs to make sure release calls are ignored (because the object is shared globally).

Singleton Boilerplate (ApplicationSettings.m):

static ApplicationSettings *sharedApplicationSettings = nil;

+ (ApplicationSettings*) getSharedApplicationSettings
{
    @synchronized(self) {
        if (sharedApplicationSettings == nil) {
            [[self alloc] init]; // assignment not done here
        }
    }
    return sharedApplicationSettings;
}

+ (id)allocWithZone:(NSZone *)zone
{
    @synchronized(self) {
        if (sharedApplicationSettings == nil) {
            sharedApplicationSettings = [super allocWithZone:zone];
            return sharedApplicationSettings;  // assignment and return on first allocation
        }
    }
    return nil; //on subsequent allocation attempts return nil
}

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

- (id)retain
{
    return self;
}

- (unsigned)retainCount
{
    return UINT_MAX;  //denotes an object that cannot be released
} 

- (void)release
{
    //do nothing
}

- (id)autorelease
{
    return self;
}

Problem

I’m sure this is a simple one, but it’s been elusive so far, and I’m stumped ... How do I declare an Ivar so that it’s accessible from ALL Classes in a project? [Don’t know if it matters, but the ivar in question is (an instance of) my Model class, whose data needs to be accessible to various view controllers.] Best as I can tell from "The Scope of Instance Variables” in The Objective-C 2.0 Programming Language ... this would be by using the “@public” directive. So I’ve tried this in the @interface block where the ivar is declared: ``` @interface ... ... @public ModelClass *theModel; @end ``` ... But when I try to refer to “theModel” in a different class, the compiler doesn’t auto-complete, and when I type it in anyway, the compiler shows: “Error: ‘theModel’ undeclared (first use in this function)”. I assume this is a question of Scope, and that I haven’t made the ivar available appropriately, but how? Somehow I need to access this, or make its pointer available somehow. Any ideas would be VERY much appreciated. Many thanks!

Original source