Re: Is there a pattern for creating an object with global scope?
Re: Is there a pattern for creating an object with global scope?
- Subject: Re: Is there a pattern for creating an object with global scope?
- From: Uli Kusterer <email@hidden>
- Date: Sat, 13 Apr 2013 14:45:16 +0200
On 13.04.2013, at 06:08, Jens Alfke <email@hidden> wrote:
> On Apr 12, 2013, at 6:54 PM, Scott Ribe <email@hidden> wrote:
>
>> Yes, extremely easy, just "create" the var, as in:
>>
>> int gFoobar = 42;
>
> YT wants to create an object, which isn’t as straightforward because you can’t have an object literal in Objective-C. Instead you declare a global pointer and initialize it early on.
>
> MyClass* gMyObject;
>
> Then early at launch time:
>
> gMyObject = [[MyClass alloc] init];
>
> That second line could go into the -applicationDidFinishLaunching: method, which is the usual place where stuff gets initialized.
Note that such a global variable has to be declared "outside any functions". I.e. best put it at the top of a .m file, right under the #includes. This is essentially what you use to implement a singleton like NSUserDefaults (unless you use dispatch_once, which might be a bit complicated for a beginner to understand, but would be the "best" solution I'm told).
However, the bad thing about exposing such a global directly is that you have no control over who accesses it when. So if you create the object in applicationDidFinishLaunching: but some document class accesses it when a document is opened, they'll quietly do nothing because gMyObject is NIL (or it could crash if you call a method on it that doesn't return an object or number).
A singleton solves that by having a method you go through to get at the singleton object:
+(MyClass*) sharedMyClass
{
if (gMyObject == nil)
gMyObject = [[MyClass alloc] init];
return gMyObject;
}
This way, no matter when the first use of your singleton is, whoever asks to get at the singleton calls [MyClass sharedMyClass] to get the object, and the first one to do so implicitly creates it. Even better, if nobody ever uses e.g. the menu items that use this singleton, it will never be created, saving on startup time and memory.
Also, since you only expose the class method, not the global variable used to store the singleton, you can turn it into a static variable, by defining it as:
static MyClass* sMyObject;
and lose the 'extern' declaration in the header. Now the only code that can access this variable directly is the code in the file that contains the definition. If someone else has a static variable of the same name, there is no collision. If someone wants to talk to this object, they *must* go through +sharedMyClass. And if you want to be really clean, declare that *static* variable in +sharedMyClass. It will still remember its value between calls (that's what 'static' means in that context), but nobody but +sharedMyClass will be able to directly access it.
Of course, since all methods called on the object will be instance methods, not class methods, they will also have access to the object in 'self', but they can't change the value of gMyObject or do other weird, wrong stuff. :-)
Cheers,
-- Uli Kusterer
"The Witnesses of TeachText are everywhere..."
http://www.masters-of-the-void.com
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden