Adapting a few Java-based singleton objects to Objective-C [duplicate] - objective-c

This question already has answers here:
Global Variables for Class Methods
(2 answers)
Closed 8 years ago.
I've decide to rewrite a java-based game prototype I've been working on in Objective-C. The iOS platform will be a better fit.
Unfortunately I'm having to learn Obj-C at the same time. In the Java game, there were a few libraries that were instantiated by the main game class, and accessed statically when needed. This meant that I could the overhead of new instances each time.
i.e.:
Game.getRNG().nextInt() or Game.getNoiseGen().noise( x, y )
I'm trying to understand the best method to replicate this in Obj-C. I've looked at examples of singletons and am trying this method, but I'm not sure if this is the best way to do this.
The above code, would apparently translate into something like:
[[[Game getInstance] getNoiseGen] noise]
Is there a better way to create a single instance of library classes and statically reference them from anywhere inside my application code?

For creating a singleton make sure you only create the static instance once, you can do this by using GCD.
+ (id)sharedInstance;
{
static dispatch_once_t once;
static id sharedInstance;
dispatch_once(&once, ^{
sharedInstance = [[self alloc] init];
});
return sharedInstance;
}
and you can then:
Game *game = [Game sharedInstance];
//...
CGPoint point = CGPointMake(x, y);
[[game noiseGen] noise:point]
//...
Singletons are considered an anti-pattern and should be avoided if possible.
Just from looking at your example you also violate the Law of Demeter, might be worth a read to see if you can improve there.

If I understand your Java model correctly there is no reason why you cannot translate it directly into Objective-C, which certainly has the advantage that you are familiar with it - helpful while you're learning a new language.
By "there were a few libraries that were instantiated by the main game class, and accessed statically when needed" I take it that either:
The main class declared global variables of the appropriate types and initialised them; or
The classes themselves have a global variable which holds a reference to an instance of themselves.
You are not generating "singletons" here, just objects you want to share. Also given that your main class created them they always exist. Combined this means you've no need to use any of the "singleton" schemes which delay creation until first use and deal with one-time thread-safe initialisation.
All you need is the model for global variables in Objective-C. In outline this is:
Declare the variable as extern in a header file
Define the variable in an implementation file
In outline, your MainGame.h:
#import "SharedGameObject.h"
#interface MainGame : NSObject
extern SharedGameObject *TheSharedGameObject;
...
#end
and MainGame.m
#import "MainGame.h"
SharedGameObject *TheSharedGameObject;
- (id) init
{
TheSharedGameObject = [SharedGameObject new];
...
}
Now every other class which import MainGame.h has access to the same shared object using TheSharedGameObject. This is the model Apple used for NSApplication and it associated NSApp global variable.
HTH

Related

How should I be using class variables in Objective-C?

This has been bugging me for a long time, and I have tried to look it up many times.
When I first began learning Objective-C, I remember looking into class variables. I saw many threads on stack overflow and elsewhere that basically said, "Objective-C doesn't support class variables like C does, but there are some workarounds."
Reading this made me shy away from using class variables, especially because I have read hundreds of times that global variables tarnish the elegance of OOP.
So I have a very open ended, opinionated, and conversational question:
Should I use class variables in objective C? Also, am I doing it right?
Here is my situation: I am making an app, and I set up a touch handling class to deal with all the input received from screen touches. The data is pretty useful, and I would like every single sprite to have access to it.
Since every object is a subclass of my GameObject class, I figure I just make a class variable, done like so:
header for GameObject class:
+(SSTouchHandler *)touchHandler;
+(void)setHandler:(SSTouchHandler *)handler;
implementation for GameObject class:
static SSTouchHandler *touchHandler = nil;
+(SSTouchHandler *)touchHandler
{
if (touchHandler)
return touchHandler;
else
return nil;
}
+(void)setHandler:(SSTouchHandler *)handler
{
touchHandler = handler;
}
Now, this works. This works beautifully.
I can refer to my handler with [GameObject touchHandler] from every place I need.
This is all I could ever want and more.
But should I use this method? Am I dirtying the beauty that is object oriented programming?
Is there a way I should touch up this process to make it work optimally?
Thanks for any and all input, I probably rambled a bit, I just don't want to proceed with a faulty game structure.
I saw many threads on stack overflow and elsewhere that basically
said, "Objective-C doesn't support class variables like C does, but
there are some workarounds.
"Class variables" make no sense in the context of C since C is not object oriented.
So I have a very open ended, opinionated, and conversational question:
Should I use class variables in objective C? Also, am I doing it
right?
This is more of a general OOP question than anything specific to Objective-C. The answer tends to be pretty subjective, but in general I'd say to avoid them unless you're trying to set a property of some sort that affects all instances of a class.
Here is my situation: I am making an app, and I set up a touch
handling class to deal with all the input received from screen
touches. The data is pretty useful, and I would like every single
sprite to have access to it.
It sounds to me like a better design pattern for this would be to pass the SSTouchHandler instance as a parameter to the initializer of the sprite objects that use it. e.g.:
#interface GameObject : NSObject
- (id)initWithTouchHandler:(SSTouchHandler *)handler;
#end
Now, if you really want to use the same instance of SSTouchHandler for every GameObject, you have two options:
1) The controller/factory that creates the GameObject objects should create and keep a reference to a single instance of SSTouchHandler, and then initialize any new GameObject instances with it. For example:
#interface GameObjectController : NSObject
#property (nonatomic, strong, readonly) SSTouchHandler *touchHandler;
- (GameObject *)newGameObject;
#end
#implementation
- (id)init
{
if ((self = [super init])) {
_touchHandler = [[SSTouchHandler alloc] init];
}
return self;
}
- (GameObject *)newGameObject
{
return [[GameObject alloc] initWithTouchHandler:self.touchHandler];
}
#end
2) You could make SSTouchHandler a shared singleton and call methods on the shared instance directly from the implementation of GameObject. However, shared singletons are discouraged in OOP because they hide dependencies and make it difficult to unit test code that depends on them. You shouldn't go down this route unless you deem it absolutely necessary.
implementation for GameObject class: ...
If you decide that the patterns above aren't suitable for your use case (and that sometimes does happen), yes that is essentially how you would implement class properties in Objective-C. One thing:
if (touchHandler)
return touchHandler;
else
return nil;
This is not necessary, you can just return touchHandler since it will be nil anyways if not set.
If it works, you're done. I think there are some improvements, though. First, you might like to use an instance var here: it's not more complicated, but it allows some flexibility in the future (e.g. if you want to make two views side by side). Also, using a bare pointer is not so good; the class here does not own the pointer, and it can be left dangling! Defining the touchHandler as a property (also an instance var) takes care of that problem.

Creating "Global Methods" [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How to create global functions in Objective-C
I am curious how it is commonly done to create global utility methods in Objective C that any Class can use.
The simple and only solution I can think of is to simply create a class, i.e. call it GlobalMethods, and just create a bunch of class methods so that they can be used without this class ever getting instantiated.
Is this a wise and valid approach? Regarding the type of methods, they might be anything, for example custom math formulas I use, etc.
There are a few common ways to make some code usable globally. Here are some, with examples from Apple's public APIs:
Create class methods on a new class. This is what you suggested. Examples: NSPropertyListSerialization, NSJSONSerialization.
Create class methods on some appropriate existing class. Example: UIKit uses a category to add class methods to NSValue, such as valueWithCGRect: and valueWithCGPoint:.
Create a singleton that understands some group of related messages. Examples: [UIApplication sharedApplication], [NSFileManager defaultManager].
Create plain old C functions. Examples: UIImagePNGRepresentation, UIRectFill, NSLog, NSStringFromCGPoint, and a pantload more.
If the code operates on some object in particular, add a method the the object's class using a category. Example: UIKit adds sizeWithFont:, drawAtPoint:withFont:, and related methods to NSString using a category.
I use that exact approach to provide my global CocoaUtil class that provides various application services.
However you can simply define global C functions that do Objective-C things; for example:
Util.h:
extern NSString *helloWorld(int i);
Util.m:
NSString *helloWorld(int i)
{
return [NSString stringWithFormat:#"Hello World %d", i];
}
However, I use the Objective-C class approach as it provides better "namespace" support, ala C++.

Dynamic Getters and Setters with Objective C

I am in a situation where I want to dynamically generate getters and setters for a class at runtime (in a similar manner to what NSManagedObject does behind the scenes). From my understanding, this is possible using resolveInstanceMethod: on a specific class. At this point, you would have to use class_addMethod to dynamically add the method based on the selector. I understand this at a theoretical level, but I haven't delved much into the obj-c runtime, so I was curious if there were any great examples of how to do this. Most of my knowledge comes from this article:
http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtDynamicResolution.html
Any thoughts / examples?
The only nice discussion I know is at Mike Ash's blog post. It's not that hard, actually.
I once needed to split a big NSManagedObject subclass into two, but decided to keep the fact an implementation detail so that I don't have to rewrite other parts of my app. So, I needed to synthesize getter and setter which sends [self foo] to [self.data foo], automatically.
To achieve that, I did the following:
Prepare the new method, already in my class.
- (id)_getter_
{
return objc_msgSend(self.data, _cmd);
}
- (void)_setter_:(id)value
{
objc_msgSend(self.data, _cmd,value);
}
Note that _cmd has the selector in it. So, usually, _cmd is either #selector(_getter_) or #selector(_setter_) in these methods, but I'm going to plug the implementation of _getter_ as the implementation of foo. Then, _cmd contains #selector(foo), and thus calls self.data's foo.
Write a generic synthesizing method:
+(void)synthesizeForwarder:(NSString*)getterName
{
NSString*setterName=[NSString stringWithFormat:#"set%#%#:",
[[getterName substringToIndex:1] uppercaseString],[getterName substringFromIndex:1]];
Method getter=class_getInstanceMethod(self, #selector(_getter_));
class_addMethod(self, NSSelectorFromString(getterName),
method_getImplementation(getter), method_getTypeEncoding(getter));
Method setter=class_getInstanceMethod(self, #selector(_setter_:));
class_addMethod(self, NSSelectorFromString(setterName),
method_getImplementation(setter), method_getTypeEncoding(setter));
}
Note that this is a class method. So self stands for the class. Note also that I didn't hardcode type encodings (which tells Objective-C runtime what the arguments of the particular method are). The syntax of type encodings is documented, but constructing by hand is very error-prone; I wasted a few days that way until Mike Ash told me to stop it. Generate it using an existing method.
Generate forwarders at the earliest possible time:
+(void)load
{
for(NSString*selectorName in [NSArray arrayWithObjects:#"foo", #"bar", #"baz",nil]){
[self synthesizeForwarder:selectorName];
}
}
This generates foo, setFoo:, bar, setBar:, and baz, setBaz:.
Hope this helps!
Another example is one I wrote, called DynamicStorage, available here:
https://github.com/davedelong/Demos
The primary impetus behind it was this question, which was asking how to use an NSMutableDictionary as the backing store for any object ivar. I wrote a class that will generate getters and setters for any #property, respecting things like a custom getter/setter name, the object memory management policy, etc. The neat thing about it is that it's using imp_implementationWithBlock() so that it only has to calculate the appropriate property name once (and then captures and saves it as part of the block).

iPhone SDK: When allocating a static variable, should I check for nil?

I often see singleton classes designed similar to the following:
#implementation SomeImplementation
static SomeClass *sharedSomeObject = nil;
+ (void) someClassMethod {
sharedSomeObject = [[SomeImplementation alloc] init];
// do something
}
#end
someClassMethod can be called at any time -- should it be checking for nil first before allocating a new instance of sharedSomeObject? Or, since sharedSomeObject is static, is the check unnecessary? Seeing code like this I always want to put an if (!sharedSomeObject) around the allocation.
Yes, absolutely! Otherwise you're creating more than one object every time your method is called. This is how we do things:
+ (SomeClass *) shared {
static SomeClass *sSingleton;
if ( ! sSingleton ) sSingleton = [SomeClass new];
return sSingleton;
}
EDIT
This answer is very old, not thread-safe, and no longer an appropriate singleton initialization method. See this Stackoverflow answer for the correct way of doing things nowadays with GCD.
When it comes to the using the Singleton design pattern with Objective-C, I can highly recommend using Matt Galagher's "SynthesizeSingleton.h" macro. It deals with all the singelton-related topics like freeing (is that a proper word?) memory if the singleton will be no longer needed.
Here's the link to the "Cocoa with Love" website which contains an article on this topic as well as a link for the download of the "SynthesizeSingleton.h" header file:
http://cocoawithlove.com/2008/11/singletons-appdelegates-and-top-level.html
You will also find a discussion on using global variables vs. using the Singleton design pattern as well as some considerations on different approaches towards using Singletons there.

Objective-C Basic Class question

So I'm a bit rusty getting back into programming and I can't seem to find a good reference for understanding the structure for what I am trying to achieve. So, without further ado I am looking at creating and Class object such as.
#import Assets.h
#interface MainRecord: NSObject {
Assets* assets;
...
}
...
#end
Having a class object within a class, do i need to initialize when the object is created in main? I want to make sure each instance created for MainRecord will always be associated with it's Assets.(in the future these will be written to a file) All of which is mainly for readability and ease of adding objects to this class.
I recommend reading (at least parts of) The Objective-C 2.0 Programming Language, a guide published by Apple. The section called "Defining a Class" will answer the bulk of your questions.
Basically, you don't initialize instance variables in main() — the class defines methods that handle its own variables. (This is common practice for object-oriented programming languages.) In Objective-C you initialize instance variables in an -(id)init method and release them in -(void)dealloc method to avoid leaking memory. For example, see all the -initWith... methods in NSString.