Re: Followup - Re: Is there a pattern for creating an object with global scope?

2013-04-15 Thread Tom Davie

On 15 Apr 2013, at 00:25, Graham Cox graham@bigpond.com wrote:

 
 On 14/04/2013, at 2:08 PM, YT y...@redwoodcontent.com wrote:
 
 My struggle is partially due to my lack of experience in OOP. I just have 
 not written enough OO code as of yet.  AND I'm very new to Objective-C. 
 Hence my lack of experience and working knowledge of Objective-C.
 
 extern int gFoobar;
 
 I understand that solution and its working for me right now.
 
 
 I understand how tempting it is to go with whatever you can get working, 
 especially when you're new to something.
 
 But in this case I believe you should resist the temptation and try and gain 
 a little more understanding before you get too far down this road.
 
 GLOBALS ARE BAD NEWS. That is a pretty good rule and well worth sticking to. 
 If you can get rid of globals (and you always can) then you should avoid 
 them. There is NO problem in application programming that requires a global 
 to solve it. Singletons are a much safer and more predictable means of 
 achieving something that has global scope but prevents the hidden 
 state/parameters problem that globals bring with them.

Wow, I really can't get my head around this one.  You make bold statements like 
GLOBALS ARE BAD NEWS (which I 100% agree with), but then follow up with 
effectively use singletons instead.  Singletons bring with them 95% of the 
problems globals bring.  They still break any attempts at threading, they still 
break any attempts at testing, they still break separation of concerns, and 
they're always avoidable.  So I'd follow up with SINGLETONS ARE BAD NEWS TOO!  
In 95% of cases where you have a singleton, you should almost certainly be 
using dependancy injection instead, or some other method of avoiding it.

Note also – simply using your app delegate as a store for things that aren't 
singletons, but only one of them is pointed at by your app delegate is also 
horrific – you're just substituting one singleton for another.

Thanks

Tom Davie
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: Followup - Re: Is there a pattern for creating an object with global scope?

2013-04-15 Thread Graham Cox

On 15/04/2013, at 8:44 PM, Tom Davie tom.da...@gmail.com wrote:

 Wow, I really can't get my head around this one.  You make bold statements 
 like GLOBALS ARE BAD NEWS (which I 100% agree with), but then follow up 
 with effectively use singletons instead.  Singletons bring with them 95% of 
 the problems globals bring.  They still break any attempts at threading, they 
 still break any attempts at testing, they still break separation of concerns, 
 and they're always avoidable.  So I'd follow up with SINGLETONS ARE BAD NEWS 
 TOO!  In 95% of cases where you have a singleton, you should almost certainly 
 be using dependancy injection instead, or some other method of avoiding it.
 
 Note also – simply using your app delegate as a store for things that aren't 
 singletons, but only one of them is pointed at by your app delegate is also 
 horrific – you're just substituting one singleton for another.


I'm not suggesting you use singletons all over the place, but judicious use of 
singletons is a reasonable and straightforward way to solve the global scope 
problem without directly using globals. Sometimes you need something with 
global scope, and the OP's use-case of preferences is a common example. Other 
things are a natural fit too, such as NSApplication.

I agree that they can bring many of the same problems with them, but some of 
the things you mention are not inherently a problem with singletons as long as 
you're aware of the issues. Threading for example, is easily taken care of. Are 
they a solution for every situation? No, I'm not suggesting they are, but I 
don't think they bring 95% of the same problems as globals. I don't know what 
you mean by dependency injection, it's not a term I've heard of, but it's 
like anything - there are good and correct solutions to a problem and there are 
others which work but are non-optimal. The craftsman needs to be aware of the 
tools at his disposal and use the appropriate one for the task at hand. Globals 
are never required, singletons occasionally. Something else altogether usually.


--Graham


___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: Followup - Re: Is there a pattern for creating an object with global scope?

2013-04-15 Thread Graham Cox

On 16/04/2013, at 10:18 AM, Graham Cox graham@bigpond.com wrote:

  I don't know what you mean by dependency injection, it's not a term I've 
 heard of


OK, I looked it up. I hadn't heard the term but I'm very familiar with the 
concept it refers to. Sometimes the service or dependent entity should be a 
singleton... I don't see that it's a substitutable solution, but one orthogonal 
to the existence of singletons.

--Graham

 
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Followup - Re: Is there a pattern for creating an object with global scope?

2013-04-15 Thread Uli Kusterer
On 15.04.2013, at 12:44, Tom Davie tom.da...@gmail.com wrote:
 Note also – simply using your app delegate as a store for things that aren't 
 singletons, but only one of them is pointed at by your app delegate is also 
 horrific – you're just substituting one singleton for another.

If it were only that! At least singletons only pull in dependencies from their 
problem domain into any module that uses them. If you instead implement them in 
the app delegate, all that code not only bloats the app delegate, its 
dependencies also make all these singletons recompile whenever only one of them 
changes.

Cheers,
-- Uli Kusterer
The Witnesses of TeachText are everywhere...
http://www.zathras.de



___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: Is there a pattern for creating an object with global scope?

2013-04-14 Thread Scott Ribe
On Apr 13, 2013, at 9:51 PM, Jens Alfke wrote:

 C++ static initializers are evil, though, at least the ones that run code. 
 They run super early, in an undefined order, with no way to specify 
 dependencies between them; so if you’re not careful they can slow down launch 
 and/or cause weird nondeterministic bugs.

They're not evil if you don't create dependencies ;-) Also, if you keep the 
number of such globals very low (I'm thinking  10), you avoid most problems.

-- 
Scott Ribe
scott_r...@elevated-dev.com
http://www.elevated-dev.com/
(303) 722-0567 voice





___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: Followup - Re: Is there a pattern for creating an object with global scope?

2013-04-14 Thread Uli Kusterer
On 14.04.2013, at 06:29, Steve Mills sjmi...@mac.com wrote:
 Oh, that's easy, once you know how to make singletons. OK, I wouldn't call it 
 easy, but it's the right thing to do.

 If the C++ Steve wrote helps you understand things better, here's a 1-to-1 
translation of that code to the equivalent in Objective C:

PreRun.h:

@interface PreRun : NSObject
{
BOOLtheVariableYouWantToBeGlobal;
}

-(PreRun*)  sharedInstance; // Usually a singleton access method is called 
defaultX or sharedX, not GetInstance like in C++.

-(void) setVar: (BOOL)b;
-(BOOL) var;// You usually don't use GetX as the name for a 
getter in Objective C. A 'get' prefix is used to indicate a method that has 
return parameters.

@end


PreRun.m:

@implementation PreRun

-(PreRun*)  instance
{
static PreRun*  sSharedInstance = nil;
if( sSharedInstance == nil )
sSharedInstance = [[PreRun alloc] init];
return sSharedInstance;
}


-(void) setVar: (BOOL)b
{
theVariableYouWantToBeGlobal = b;
}

-(BOOL) var
{
return theVariableYouWantToBeGlobal;
}

@end

 In a file that wants to use that variable:

[[PreRun instance] setVar: YES];

As others mentioned, you could use dispatch_once for thread safety (but I don't 
think threading is a topic you want to tackle at this point, save that for 
later and save yourself a lot of pain and random bugs that sometimes happen and 
sometimes don't). Also, you would probably use @property BOOL (assign) var; and 
@synthesize var = theVariableYouWantToBeGlobal; to save yourself the work of 
writing setVar:/var methods and declaring the instance variable 
'theVariableYouWantToBeGlobal'.

Some people also believe in overriding -init, -retain, -release and 
-retainCount to keep people from creating a second instance of this object, but 
that's more defensive coding than necessary. I just mention it because it's the 
moral equivalent to Steve's making the constructor private.

Cheers,
-- Uli Kusterer
The Witnesses of TeachText are everywhere...
http://www.masters-of-the-void.com



___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Followup - Re: Is there a pattern for creating an object with global scope?

2013-04-14 Thread Graham Cox

On 14/04/2013, at 2:08 PM, YT y...@redwoodcontent.com wrote:

 My struggle is partially due to my lack of experience in OOP. I just have not 
 written enough OO code as of yet.  AND I'm very new to Objective-C. Hence my 
 lack of experience and working knowledge of Objective-C.
 
 extern int gFoobar;
 
 I understand that solution and its working for me right now.


I understand how tempting it is to go with whatever you can get working, 
especially when you're new to something.

But in this case I believe you should resist the temptation and try and gain a 
little more understanding before you get too far down this road.

GLOBALS ARE BAD NEWS. That is a pretty good rule and well worth sticking to. If 
you can get rid of globals (and you always can) then you should avoid them. 
There is NO problem in application programming that requires a global to solve 
it. Singletons are a much safer and more predictable means of achieving 
something that has global scope but prevents the hidden state/parameters 
problem that globals bring with them. Globals tie together parts of your 
program in ways that are not obvious, and as a result lead to bugs that can be 
extremely hard to track down. Decoupling each part of your app from every other 
part as far as possible is a good aim - globals instantly spoil that. Note that 
singletons don't lead to the same problem since the singleton object itself can 
be self-contained, and any state associated with it is at least boxed into that 
object, making debugging less of a problem. About the only excuse for globals 
are as a shortcut, e.g. NSApp instead of +[NSApplication sharedApplication] but 
even there it's arguably bad style.

When I started in programming globals were the only variables there were 
(BASIC, circa 1979) and that's one reason why this language gained such a 
notorious reputation. It's a pity better languages perpetuated the existence of 
globals - if they're there, you should use them, right? Wrong. Getting rid of 
globals is arguably the single best thing you can do to improve the quality of 
your code as you move from first steps to more ambitious projects. 

  I have a PreRun Class that defines the object and I instantiate in main.m 
 just before the line 
 return NSApplicationMain(argc, (const char **)argv);


This sounds like a bad idea to me. First, it means you're modifying main.m 
which is almost never necessary (there's a reason that this file is supplied in 
a standard form and placed into the 'support files' group, out of harm's way). 
Second it means you're wasting time instantiating an object that isn't needed 
for a long time yet, if ever. Using a singleton is cleaner, because it will 
only be instantiated at its first point of use (and if never used, will never 
be instantiated).


 runs in main.m.  The object instance persists the entire program run. THEN I 
 simply extern the global var that holds the pointer to the object in all of 
 the Class files where its required to access it.  
 
 It may be a violation of OOP theory and application, it may be considered a 
 kludge BUT it works right now.  I am willing to move to a conventional OOP 
 solution if I could figure out how.


Many replies have shown you how - make a class method that returns the object, 
instantiating it once. Using a static variable within the class method ensures 
that it happens only once. You should import the class header where code makes 
use of the singleton, rather than use an 'extern' reference.

 Reading Apple Documentation is like reading UNIX Man pages - groan, beat me 
 with a stick but don't make me read UNIX Man Pages - sigh.

Better get used to it, because apart from voluntary help via this list and 
others, that's how you're going to learn about classes. In fact the docs aren't 
as terse as man pages, and there are plenty of other guides that show you how 
classes are used in a broader context.

--Graham

P.S. Tip: don't change the subject line when replying to postings, it prevents 
all the replies appearing in the same thread.
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: Is there a pattern for creating an object with global scope?

2013-04-13 Thread Uli Kusterer
On 13.04.2013, at 06:08, Jens Alfke j...@mooseyard.com wrote:
 On Apr 12, 2013, at 6:54 PM, Scott Ribe scott_r...@elevated-dev.com 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 (Cocoa-dev@lists.apple.com)

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: Is there a pattern for creating an object with global scope?

2013-04-13 Thread Tom Davie

On 13 Apr 2013, at 13:45, Uli Kusterer witness.of.teacht...@gmx.net wrote:

 On 13.04.2013, at 06:08, Jens Alfke j...@mooseyard.com wrote:
 On Apr 12, 2013, at 6:54 PM, Scott Ribe scott_r...@elevated-dev.com 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;
 }

Just a heads up, if you really want global state, and really think that a 
singleton is the right way to go (I'm not gonna get into why you shouldn't 
think these things as the entire premise of the thread is that you do), then 
the singleton pattern is much better implemented as:
+ (instancetype)sharedMyClass
{
static MyClass *_sharedMyClass = nil;
static dispatch_once_t token;
dispatch_once(token, ^
{
_sharedMyClass = [[MyClass alloc] init];
});
return _sharedMyClass;
}

This makes the access to the singleton thread safe when it's first created.  Of 
course, you then get into the nightmare of trying to maintain thread safety 
when you have a chunk of global state lying around, but that's a whole 
different story.

Thanks

Tom Davie
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: Is there a pattern for creating an object with global scope?

2013-04-13 Thread Scott Ribe
On Apr 12, 2013, at 10:08 PM, Jens Alfke wrote:

 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.

Oh, right, I work in Objective-C++, so I don't have that limitation, and always 
forget about the plain C rules.

-- 
Scott Ribe
scott_r...@elevated-dev.com
http://www.elevated-dev.com/
(303) 722-0567 voice





___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: Is there a pattern for creating an object with global scope?

2013-04-13 Thread Jens Alfke

On Apr 13, 2013, at 6:38 AM, Scott Ribe scott_r...@elevated-dev.com wrote:

 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.
 
 Oh, right, I work in Objective-C++, so I don't have that limitation, and 
 always forget about the plain C rules.

C++ static initializers are evil, though, at least the ones that run code. They 
run super early, in an undefined order, with no way to specify dependencies 
between them; so if you’re not careful they can slow down launch and/or cause 
weird nondeterministic bugs.

(I have spent time on at least one huge C++ project ripping out all static 
initializer functions/constructors, for exactly those reasons.)

—Jens
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Followup - Re: Is there a pattern for creating an object with global scope?

2013-04-13 Thread YT
First just to clear a distraction...  

I didn't want to actually create my own version of Preferences.  In fact that 
was a mistake to even mention it.  Sorry, I was flailing in my mind trying to 
describe what I was struggling with and out came Preferences as an example.  
Totally throw away the notion of creating a Preferences Object.

My struggle is partially due to my lack of experience in OOP. I just have not 
written enough OO code as of yet.  AND I'm very new to Objective-C. Hence my 
lack of experience and working knowledge of Objective-C.

Scott Ribe sited a working example that I could instantly understand, since I 
have lots of experience in good 'ole Standard C. 

Yes, extremely easy, just create the var, as in:

int gFoobar = 42;

Then reference it elsewhere as:

extern int gFoobar;

I understand that solution and its working for me right now.  I have a PreRun 
Class that defines the object and I instantiate in main.m just before the line 
return NSApplicationMain(argc, (const char **)argv);
runs in main.m.  The object instance persists the entire program run. THEN I 
simply extern the global var that holds the pointer to the object in all of the 
Class files where its required to access it.  

It may be a violation of OOP theory and application, it may be considered a 
kludge BUT it works right now.  I am willing to move to a conventional OOP 
solution if I could figure out how.

Reading Apple Documentation is like reading UNIX Man pages - groan, beat me 
with a stick but don't make me read UNIX Man Pages - sigh.

As suggested I read some on NSUserDefaults - I'm not sure how this would 
provide what I need, perhaps more reading here.

As Suggested I looked up the notion of a Singleton and Creating a Singleton 
Instance - Looks promising BUT since I have little experience to date on 
deciphering Apple Objective-C documentation it has created more unanswered 
questions rather than producing working code. SIGH!  More reading in my future 
and stumbling in the dark.  

YT





.




___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Followup - Re: Is there a pattern for creating an object with global scope?

2013-04-13 Thread Steve Mills
On Apr 13, 2013, at 23:08:41, YT y...@redwoodcontent.com wrote:

 int gFoobar = 42;
 
 Then reference it elsewhere as:
 
 extern int gFoobar;
 
 I understand that solution and its working for me right now.  I have a PreRun 
 Class that defines the object and I instantiate in main.m just before the 
 line 
 return NSApplicationMain(argc, (const char **)argv);
 runs in main.m.

Instead of doing it there, add an NSApplicationDelegate subclass and do your 
initialization in the applicationWillFinishLaunching method. Read up on that. 
This is all good stuff to learn if you want to write good Mac or iOS apps.

 The object instance persists the entire program run. THEN I simply extern the 
 global var that holds the pointer to the object in all of the Class files 
 where its required to access it.  
 
 It may be a violation of OOP theory and application, it may be considered a 
 kludge BUT it works right now.  I am willing to move to a conventional OOP 
 solution if I could figure out how.

Oh, that's easy, once you know how to make singletons. OK, I wouldn't call it 
easy, but it's the right thing to do.

PreRun.h:

class PreRun
{
private:
// Static variable that holds the only instance of this class:
static PreRun*  instance;
// The variable:
booltheVariableYouWantToBeGlobal;

// Private ctor so nobody else can create this:
PreRun(void)
: theVariableYouWantToBeGlobal(false) // Inits the member var.
{} // Nothing else to do here.
public:

static PreRun* GetInstance(void)
{
if(instance == nil)
instance = new PreRun;

return instance;
}

void SetVar(const bool b) { theVariableYouWantToBeGlobal = b; }
bool GetVar(void) const { return theVariableYouWantToBeGlobal; }
};


PreRun.cpp:

// Automatic initializer sets the instance to nil:
bool PreRun::instance = nil;


In a file that wants to use that variable:

PreRun::GetInstance()-SetVar(true);

Now, this doesn't handle the case of threaded apps where multiple threads might 
be trying to set and/or get the value at the same time. That's a whole other 
discussion. And, you can always simplify this example by making the member var 
public instead of private and doing away with the Set/GetVar methods, but 
that's not good form either.

--
Steve Mills
Drummer, Mac geek


___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Is there a pattern for creating an object with global scope?

2013-04-13 Thread Allan Odgaard
On Apr 14, 2013, at 10:51, Jens Alfke j...@mooseyard.com wrote:

 C++ static initializers are evil, though, at least the ones that run code. 
 They run super early, in an undefined order, with no way to specify 
 dependencies between them; so if you’re not careful they can slow down launch 
 and/or cause weird nondeterministic bugs.

That would be when declared in the file scope. You can give them function scope 
which means they are not initialized before entering the function, and with 
C++11 this is thread-safe (though in practice it was also thread-safe before, 
unless you disabled it).

So the way to do this would be to wrap your C++ global object in a function 
much like the sharedInstance idiom of Objective-C:

  MyPreferences global_preferences ()
  {
static MyPreferences instance;
return instance;
  }

In Objective-C++ you can do something like the above when implementing 
sharedInstance:

  + (MyPreferences*)sharedInstance
  {
static MyPreferences* instance = [MyPreferences new];
return instance;
  }

This gives you a lazily constructed singleton object.

 (I have spent time on at least one huge C++ project ripping out all static 
 initializer functions/constructors, for exactly those reasons.)

As indicated above, the unpredictable construction order can be solved by 
avoiding the file scope, though one issue which remains is that static objects 
will be destroyed during program termination, and this happens without any 
implicit cancellation of running threads. So if you have a global object shared 
with other threads, you should use heap storage or ensure all threads (that may 
use it) has finished before terminating the application.

A simple way to change to heap storage and still get the lazy thread-safe 
construction is something like:

  MyPreferences global_preferences ()
  {
static auto instance = new MyPreferences;
return *instance;
  }

It is however a nice feature to have all your objects destroyed at program 
termination.


___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: Is there a pattern for creating an object with global scope?

2013-04-13 Thread Jens Alfke

On Apr 13, 2013, at 10:02 PM, Allan Odgaard odga...@simplit.com wrote:

 C++ static initializers are evil, though, at least the ones that run code. 
 They run super early, in an undefined order, with no way to specify 
 dependencies between them; so if you’re not careful they can slow down 
 launch and/or cause weird nondeterministic bugs.
 
 That would be when declared in the file scope. You can give them function 
 scope which means they are not initialized before entering the function

Correct — and actually the way I fixed most of those static variable 
initializers [in Chrome btw] was to move them inside the functions that used 
them (or wrap them in functions.)

—Jens
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Is there a pattern for creating an object with global scope?

2013-04-12 Thread YT
Perhaps my approach is wrong. Looking for advise. 

So I'd like to define a Class called Preference.

In main.m I'd like to create an object called myPreferences before the code line

return NSApplicationMain(argc, (const char**)); is run;

I assume the object myPreferences will persist the life of the program. 

So how can I make the ID of myPreferences known to all objects in the program?

Is this even possible?

OK! So I'm trying to create an object with global scope so all other objects 
can get and put data in it.

AND OK! Its true I'm not yet a mature Objective-C programmer.  Ya know one that 
doesn't know what I can't do.

YT
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Is there a pattern for creating an object with global scope?

2013-04-12 Thread Graham Cox

On 13/04/2013, at 11:30 AM, YT y...@redwoodcontent.com wrote:

 Perhaps my approach is wrong. Looking for advise. 
 
 So I'd like to define a Class called Preference.
 
 In main.m I'd like to create an object called myPreferences before the code 
 line
 
 return NSApplicationMain(argc, (const char**)); is run;
 
 I assume the object myPreferences will persist the life of the program. 
 
 So how can I make the ID of myPreferences known to all objects in the program?
 
 Is this even possible?
 
 OK! So I'm trying to create an object with global scope so all other objects 
 can get and put data in it.
 
 AND OK! Its true I'm not yet a mature Objective-C programmer.  Ya know one 
 that doesn't know what I can't do.



Tip: don't reinvent the wheel. There is already a class, NSUserDefaults, which 
is designed for this purpose.

The use of global variables is strongly discouraged, but you can create the 
equivalent using a singleton object. NSUserDefaults provides this using 
+[NSUserDefaults standardUserDefaults] which is accessible from every part of 
your app at all times.

You probably don't really want to access preferences prior to running 
NSApplicationMain - I can't think of a sensible use case for that. Instead, 
just access each preference at the point where it's actually required - don't 
attempt to set up a whole bunch of state before anyone really needs it, it just 
slows down launch - do it lazily. For app-wide state, the NSApplication 
delegate method -applicationDidFinishLaunching is often a good place.

NSUserDefaults also provides a mechanism (-[NSUserDefaults registerDefaults]) 
for setting initial values for preferences from a plist resource which is 
useful if any of your default preferences are something other than 0/nil/NO.


--Graham


___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Is there a pattern for creating an object with global scope?

2013-04-12 Thread Scott Ribe
On Apr 12, 2013, at 7:30 PM, YT wrote:

 Is this even possible?

Yes, extremely easy, just create the var, as in:

int gFoobar = 42;

Then reference it elsewhere as:

extern int gFoobar;

***NOW*** whether or not this is a good thing to do, particularly for your 
preferences, and also some details about extern var declarations/definitions 
that vary between versions of C, are different questions ;-)

-- 
Scott Ribe
scott_r...@elevated-dev.com
http://www.elevated-dev.com/
(303) 722-0567 voice





___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Is there a pattern for creating an object with global scope?

2013-04-12 Thread Jens Alfke

On Apr 12, 2013, at 6:54 PM, Scott Ribe scott_r...@elevated-dev.com 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.

That said, Graham is right that you should use NSUserDefaults to store 
preferences instead of making your own class.

—Jens
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: Is there a pattern for creating an object with global scope?

2013-04-12 Thread Alex Zavatone
FYi, it's advice, not advise.

Advice is what you give, advise is the giving of advice.

But I like Matt Galloway's singleton approach for a class you can import and 
use everywhere.

http://www.galloway.me.uk/tutorials/singleton-classes/


On Apr 12, 2013, at 9:30 PM, YT wrote:

 Perhaps my approach is wrong. Looking for advise. 
 
 So I'd like to define a Class called Preference.
 
 In main.m I'd like to create an object called myPreferences before the code 
 line
 
 return NSApplicationMain(argc, (const char**)); is run;
 
 I assume the object myPreferences will persist the life of the program. 
 
 So how can I make the ID of myPreferences known to all objects in the program?
 
 Is this even possible?
 
 OK! So I'm trying to create an object with global scope so all other objects 
 can get and put data in it.
 
 AND OK! Its true I'm not yet a mature Objective-C programmer.  Ya know one 
 that doesn't know what I can't do.
 
 YT
 ___
 
 Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)
 
 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:
 https://lists.apple.com/mailman/options/cocoa-dev/zav%40mac.com
 
 This email sent to z...@mac.com


___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com