I saw a singleton example on objective-c book. However, I don't know if there is difference of meaning of 'singleton' definition between objective-c and other langs. Can this [[SingletonClass alloc] init] still be used to create a new object? If yes, how to guarantee there is only one object in the memory?
#import "SingletonClass.h"
#implementation SingletonClass
static SingletonClass *sharedInstance = nil;
// Get the shared instance and create it if necessary.
+ (SingletonClass*)sharedInstance {
if (sharedInstance == nil) {
sharedInstance = [[super allocWithZone:NULL] init];
}
return sharedInstance;
}
// We can still have a regular init method, that will get called the first time the Singleton is used.
- (id)init
{
self = [super init];
if (self) {
// Work your initialising magic here as you normally would
}
return self;
}
If you want a true singleton, i.e. an object that can be instantiated only once, take a look at Apple's documentation: Creating a Singleton Instance.
Basically, the idea is to override a number of methods related to allocating and managing objects: +allocWithZone (which is called by +alloc), -retain, -release, -copyWithZone, etc., so that it becomes quite difficult to create more than one instance of your singleton class. (It's still possible to create a second instance by calling the runtime directly, but this should be enough to get the point across.)
Pretty much every blogger who has ever written about Objective-C in any capacity has offered an opinion on how to implement singletons. Many of those opinions seem pretty good, and most of them are fairly similar. It's clear that Dave DeLong knows what he's talking about, and his piece on singletons is short, sweet, and gets straight to the point.
I don't know if there is difference of meaning of 'singleton' definition between objective-c and other langs.
It follows the common definition of languages derived from C.
Can this [[SingletonClass alloc] init] still be used to create a new object?
Yes
If yes, how to guarantee there is only one object in the memory?
Avoid enforcing the pattern (e.g. do not force it to be a singleton). Just make a normal object. Then if you really want only one instance, create an instance and save it someplace for reuse (your app delegate is one typical place for this, because it is typically created once per execution).
In practice, most (>95%) ObjC singleton implementations i've seen in the wild are used for the wrong reasons, and would have been better or as good as normal objects.
Every solution linked in the answers so far has (at minimum) subtle problems, dangers, or undesirable side-effects.
There is no language support for singletons, but you can do it by hand. Look at the singleton example here. It doesn't look like it is thread-safe, though. I would allocate the object in +initialize instead of +sharedManager.
You can create a singleton in Objective-C by doing the following:
+(MyAPI *)shared {
static dispatch_once_t queue;
static MyAPI *singleton = nil;
dispatch_once(&queue, ^{
singleton = [[MyAPI alloc] init];
});
return singleton;
}
This will also ensure that it is thread safe. Without using the dispatch_once you run the risk of multiple threads trying to access it at the same time when one is in the middle of allocating it, and the other is trying to use it.
Singleton class is used to save the data for use anywhere in app.
//SingletonObject
#define saveDataSingletonObject ((SaveDataSingleton*)[SaveDataSingleton sharedManager])
#interface SaveDataSingleton : NSObject
#property (nonatomic,strong) NSMutableArray *DataArr;
+ (id)sharedManager;
-(void)clearAllSaveData;
#end
#implementation SaveDataSingleton
#synthesize DataArr;
+ (id)sharedManager {
static SaveDataSingleton *sharedManager;
if(!sharedManager) {
#synchronized(sharedManager) {
sharedManager = [SaveDataSingleton new];
}
}
return sharedManager;
}
-(void)clearAllSaveData{
DataArr=nil;
}
- (id)init {
if (self = [super init]) {
DataArr = [[NSMutableArray alloc]init];
}
return self;
}
// using setter getter save and retrieve data
+(void)setDataArr:(NSMutableArray *)Dataarr
{
self.DataArr = [[NSMutableArray alloc]initWithArray:Dataarr];
}
+(NSMutableArray *)DataArr
{
return self.DataArr;
}
#end
Save and Retrieve data // Use singleton Object
// save data using setter function.
[saveDataSingletonObject setDataArr:Array];
//fetch data using getter function.
NSArray *arr=[saveDataSingletonObject DataArr];
Related
I am trying to update my UIProgressView with some data from a method of my utility class.
Now, just because for updating my UIProgressView, i am holding that method in my view controller class and everything works fine. Because i can reach the loop in that method with a global variable so i can update my progress. But if i want to move this method to my utility class, what am i supposed to do to keep informed my UIProgressView. Thanks.
What I would suggest is to redesign your utility class to be a singleton
Here is an example of code of your utility class:
UtilityClass.h file:
#interface UtilityClass : NSObject
+ (UtilityClass *)sharedInstance;
- (CGFloat)awesomeMehod;
#end
UtilityClass.m
#implementation UtilityClass
+ (id)sharedInstance
{
static UtilityClass *_instance;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instance = [[UtilityClass alloc] init];
});
return _instance;
}
- (id)init
{
self = [super init];
if (!self) return nil;
// Regular initialization, however keep in mind that it will be executed just once
return self;
}
- (CGFloat)awesomeMethod
{
return 42.0f
}
#end
Now from your view controller you will call
CGFloat progress = [[UtilityClass sharedInstance] awesomeMethod];
[self.progressView setProgress:progress];
keep in mind several things:
It's one of possible approaches and I would go and read about various
design patterns that might come in handy one day
Probably a good idea to refresh knowledge on view controllers and the way they interact
For class to become a proper singleton, you also should override
methods such as alloc, init, initWithZone, dealloc, release
etc (list of methods to override will vary if you use ARC), here is
an example of doing that, although dispatch_once takes care of
#synchronize() call. For now, as long as you "instantiate" you class only
through calling sharedInstance class method you will be fine.
i used to using singleton like that:
///.h
#interface ASMyController:NSViewController
+(id)myViewController;
#end
////.m
static ASMyController* singleton = nil;
#implementation ASMyController
+(id)myViewController
{
if(nil == singleton)
{
singleton = [[[self class] alloc] init];
}
return singleton;
}
-(id)init
{
self = [super initWithNibName:#"test" bundle:xxxx];
if(self)
{
..............................
}
return self;
}
#end
The singleton work well in non-document-base application.However, in document - base Application, each instance of app share the same static variable. In my first design, the singleton one and only in a app instance but not all app instances.
So is it mean that I should reconsider the design ? Or I can make the singleton to a dict. and I can use key to get a singleton of current instance? Or any other good idea for me?
I pray that my poor English will not trouble u..
The very name of your method, my..., suggests something rather fundamental is being misunderstood - there is just one singleton shared by everybody, objects don't own their own copies of singletons.
A singleton is not a way to avoid a variable, it appears you might be trying to use [ASMyController myViewController] instead of an instance variable self->myViewController (often abbreviated to myViewController) or a property self.myViewController.
You probably need to look at something along the lines of:
#interface ASMyDocument : NSDocument
{
ASMyContoller *myViewController;
}
However your original design suggests you should really review the relationships between/meanings of classes, instances, singletons, has-a, is-a etc.
This question already has answers here:
What does #synchronized() do as a singleton method in objective C?
(6 answers)
Closed 3 years ago.
After reading the responses to a question about singletons in Objective C it appears that each solution makes some tradeoff in regards to threading in the instance accessor. i.e.
#synchronized(self)
{
if (sharedInstance == nil)
sharedInstance = [[MySingleton alloc] init];
}
return sharedInstance;
This essentially single-threads access to the singleton, and if it's something that's used frequently in an operation, seems like something that could cause threads to unnecessarily contend.
What's the downside to simply using the class object as the singleton instance, and exposing functionality via class methods, i.e.
#interface MySingleton : NSObject {
}
+ (void)doSomething;
#end
#implementation MySingleton
+ (void)initialize {
//do some setup if necessary
}
+ (void)doSomething {
//do something
}
#end
In this way we avoid doing the lock + check every time we want to reference the singleton object and we can also eliminate having to store it in a local or method ivar.
This approach also lets the runtime guarantee that only one instance (the Class object) exists in the system at any given time.
EDIT
There's more here than just threading, with a traditional singleton you usually write code like this:
MySingleton *instance = [MySingleton getSharedInstance];
NSObject *someResult = [instance getResult];
//or
if (instance.someProperty) {
//do something
}
However if your singleton is a class instance, you essentially eliminate the need call getSharedInstance all the time. Consider this code:
NSObject *someResult = [MySingleton getResult];
//or
if ([MySingleton someProperty]) {
//do something
}
I hear the point that you have to store your data in file local static variables, or in global variables (yuck). But it's really not all that different from a traditional singleton with the exception that you lose Objective-C 2.0 properties (instead you have to use traditional accessor methods).
Here's one key tradeoff for me that seems like a win. In a traditional singleton you end up overriding -copyWithZone, +allocWithZone, -retain, -retainCount, -release and -autorelease if you really want to get things right.
This seems like an awful lot of work to do every time you want to write a simple Singleton object (they happen to be pretty useful). So why not simply just replace it with this:
#implementation MySingleton
+ (void)initialize {
//do your setup
}
- (id)init {
NSAssert(NO, #"You should read the documentation on singletons.");
}
#end
It's a lot lighter in terms of code, and unless your consumers are really sneaky they won't ever create two instances.
Get to the point already
My question is really this:
Is there any drawback to using the Class object as the instance of your singleton?
It seems like you can take all the same steps in terms of threadsafety, memory efficiency etc. without having to remember to override so many methods and accessors or litter your code with instance checks.
With iOS 4.0 or later, by far the best solution is to just use dispatch_once, as in
+ (id)sharedInstance {
static dispatch_once_t predicate;
dispatch_once(&predicate, ^{
sharedInstance = [[MyClass alloc] init];
});
return sharedInstance;
}
You may also want to consider using a single dispatch_queue to serialize access to the internals of a class. If all your public methods just run a block on the same dispatch_queue then you won't have to worry about concurrency issues.
This is my first post on Stack Overflow... (so prepare for stupidity)
I think there is a hybrid solution that might be useful.
I want to set and get (global) values out of a singleton class without having calling "getSharedInstance". I'd want the code to look like this...
frameRate = Singleton.frameRate;
Singleton.frameRate = 42;
To achieve this, each variable we need to store in the singleton has a getter and setter class method. The class method then goes to an instance to store the data in an ivar. The instance isn't directly accessed by the main program.
The getter looks like this:
+ (int) frameRate
{
return [[Singleton instance] ivarFrameRate];
}
The (ugly) instance call is hidden inside the class code.
By calling the instance method here, the class method will automatically instantiate an object when first used. Once the singleton is instantiated, the instance stores ivars conventionally. Here, I am prefixing with "ivar" make the ivar explicit.
#property int ivarFrameRate;
and
#synthesize ivarFrameRate;
This automatically creates conventional getter (and setter) methods to access the ivar.
(edit - here is a complete example)
// Singleton.h
#import <Foundation/Foundation.h>
#interface Singleton : NSObject
{
float ivarFrameRate
}
#property float ivarFrameRate;
- (id) init;
+ (Singleton *) instance;
+ (float) frameRate;
+ (void) setFrameRate:(float)fr;
#end
and
// Singleton.m
#import "Singleton.h"
#implementation Singleton
#synthesize ivarFrameRate;
static Singleton* gInstance = NULL;
+ (Singleton*)instance
{
#synchronized(self)
{
if (gInstance == NULL)
gInstance = [[self alloc] init];
}
return(gInstance);
}
- (id)init
{
self = [super init];
return self;
}
+ (float) frameRate
{
return [[Singleton instance] ivarFrameRate];
}
+ (void) setFrameRate:(float)fr;
{
[[Singleton instance] setIvarFrameRate:fr];
}
This is fine, but still just changes your circumstances rather than fixes your problems. Unless you don't have any actual data tied to your singleton, in which case this will work just fine. Anytime you access central data you will need to properly make it thread-safe.
Additionally, without some kind of iVar I don't know of a way to store data (that is intended) directly in a class.
In the example above I would code it in this way, getting the same result as you are proposing and only taking the performance hit if we are creating/re-creating the singleton:
if (sharedInstance)
return sharedInstance;
#synchronized(self)
{
if (sharedInstance == nil)
sharedInstance = [[MySingleton alloc] init];
}
return sharedInstance;
Keep in mind that either way, if you are accessing data that is potentially changing on different threads then you'll have to make that code thread-safe anyway, either with very careful planning or using code to ensure there are no problems. I'd recommend a mix, but when in doubt the latter when at all possible. =)
If you use a class as your singleton, the only way to store data would be to use static file variables and global variables. If you are going to go so far that you make a class you don't plan to instantiate, you might as well just use standard C functions:
void doSomething(void);
void doSomething() {
//do something
}
I know Singleton pattern has been discussed so much. But because I'm not fully understand the memory management mechanism in Objective-C, so when I combined Singleton implementation with multithreading, I got a big error and cost me a whole day to resolve it.
I had a singleton object, let's call it ObjectX. I declared an object inside ObjectX that will detach a new thread, let's call that object objectWillSpawnNewThread, when I called
[[ObjectX sharedInstance].objectWillSpawnNewThread startNewThread];
The new thread could not be executed correctly, and finally I found out that I should not declare the object objectWillSpawnNewThread inside the singleton class.
Here are my questions:
How does Objective-C allocate static object in the memory? Where does Objective-C allocate them(Main thread stack or somewhere else)?
Why would it be failed if we spawn a new thread inside the singleton object?
I had searched the Objective-C language [ObjC.pdf] and Objective-C memory management document, maybe I missed something, but I currently I could not find any helpful information.
Learn the memory management rules. They are simple and in a week you’ll have the time investment back.
Forget about singletons. More precisely, forget about singletons enforced by code. They are unnecessarily complicated and 99% of the time are simply bad design.
Read Singletons are Pathological Liars by Miško Hevery, read it carefully, read all of the related blog posts and think about it. Most of the time there is no real need for a class to enforce having a single instance. Usually you can get around the problem by creating some kind of Factory class that will create most instances for you and wire them together:
#interface Factory {
id classYouWantJustOneInstanceOf;
}
- (id) wireMainController;
#implementation Factory
- (id) init {
[super init];
// No “sharedFoo” stuff necessary. Foo is a plain
// class without singleton boilerplate, easily testable.
classYouWantJustOneInstanceOf = [[Foo alloc] init];
return self;
}
- (id) wireMainController {
id controller = [[SomeClass alloc] init];
// Dependencies set explicitly, good.
[controller setFoo:classYouWantJustOneInstanceOf];
return [controller autorelease];
}
#implementation UIApplicationDelegate
- (void) applicationDidFinishLauching: (UIApplication) app {
// Now all your “singletons” will get created,
// no funny static stuff.
factory = [[Factory alloc] init];
controller = [[factory wireMainController] retain];
[window addSubview:controller.view];
// up and running
}
- (void) dealloc {
[controller release];
// Now all your “singletons” will get released.
[factory release];
[super dealloc];
}
I know this feels a bit uneasy compared to “simple” [Foo sharedFoo], but it’s worth it, trust me.
The advantages of this solution, in case they are not apparent:
No singleton boilerplate in your classes. No static shared instances, no thread synchronization, nothing.
Explicit dependency management. If class A needs instance of B to do its work, you can see that from a public setter or a constructor parameter of A. No suprise dependencies inside the implementation file. And if you need to wire A differently, say for testing purposes, it’s easier when the dependencies are explicit (as opposed to calling [B sharedB]).
Clear object lifecycle. No static variables, no static initialization and no lazy initialization unless you really want it. You know when objects get created and you can deallocate everything you create.
Note that this is a simplified case, so that the division between application delegate and Factory seems a bit pedantic, but in a real case it makes perfect sense (see the Principle of single responsibility).
It's hard to say what you did wrong unless you post some code, but there's no magic involved with singleton objects. There is no suuch thing as a static object.
Question 1:
All Objective-C objects are allocated from the heap. You can declare pointers to them from any scope, but somewhere in your code, directly or indirectly, the object's class must be sent the alloc message and the resulting pointer initialised and assigned to your pointer. Your object's instance variables must be initialised in your object's init method. So one way to implement your singleton would be as follows:
// Header
#interface ObjectX : NSObject
{
SpawnObject* objectWillSpawnNewThread;
}
+(ObjectX*) sharedInstance;
// Implementation
#implementation ObjectX
-(id) init
{
self = [super init];
if (self != nil)
{
objectWillSpawnNewThread = [[SpawnObject alloc] init];
}
return self;
}
+(ObjectX*) sharedInstance
{
static ObjectX* sharedInstance;
#synchronized([ObjectX class])
{
if (sharedInstance == nil)
{
sharedInstance = [[ObjectX alloc] init];
}
}
return sharedInstance;
}
#end
Question 2:
Can't tell you the answer, unless you post your code and the error message. However, one common problem is forgetting to set up an autorelease pool inside the new thread.
I've found this snippet of code on the net. It sets up an NSMutableArray in a way I've not seen before ( I'm an Obj-C newb). Can someone explain what it's doing and why you would do it this way? Particularly the #syncronized, static and little plus sign on the method signature.
add the following to the .h file:
+(NSMutableArray *)allMySprites;
add the following to he .m file after implementation:
static NSMutableArray * allMySprites = nil;
+(NSMutableArray *)allMySprites {
#synchronized(allMySprites) {
if (allMySprites == nil)
allMySprites = [[NSMutableArray alloc] init];
return allMySprites;
}
return nil;
}
Adding to the other responses ... the posted code is wrong. It should be more like this:
#implementation SpriteManager
+ (NSMutableArray*) allMySprites {
#synchronized(self) {
if (allMySprites == nil) {
allMySprites = [[NSMutableArray alloc] init];
}
}
return allMySprites;
}
#end
It makes no sense to #synchronize on nil. Using self in a class method refers to the class and not the instance. Also the 'return nil' in the original code is pointless.
A better approach where the #synchronized can be completely avoided is to use a class initializer method:
#implementation SomeClass
+ (void) initialize
{
allMySprites = [[NSMutableArray alloc] init];
}
#end
The initialize methods are guaranteed to be called before the class is used.
The + sign indicates the method is static as opposed to instance methods. It means the method belongs to the class rather than each instance of a class (just like static things in Java and C#). #synchronized acquires a lock on the object specified (like lock statement in C#). It means no other thread can enter a #synchronized block with that object.
The code as a whole is trying to initialize a singleton collection the first time (when it's not initialized yet) and cache it for use in subsequent calls to that method. The synchronized block creates a critical section to make the initialization part safe in case of a race condition where two threads try to get the value roughly the same time while it's still doing the initialization.
It's an implementation of the Singleton design pattern, basically a way of making sure that you only have one copy of your MySprites.
The details:
The + means that this is a class method
The #syncyronize makes access to the allMySprites variable thread-safe (there are a few caveats but that's the one line summary)
I believe that the static limits the scope of the variable only to the file