Singleton again, but with multi-thread and Objective-C - objective-c

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.

Related

Objective C - is init a bad place to implement a factory?

I implemented the old init-as-a-factory pattern, but in one particular case (but not others!) I get a warning from the analyser regarding memory leaks. And indeed, looking at the Cocoa Memory Management Policy rules, it is alloc, not init, which can return +1-retain-count objects.
So it appears that:
Releasing self and returning a new object from init is, strictly speaking, against the rules.
Many places on the internet promote this technique, and because of the tandem nature of alloc/init this does work.
The analyser sometimes complains about this, and sometimes doesn't.
So... have we been doing this wrong all along?
you can implemented init like this, which should release self to balance the retain count from alloc call.
- (id)initWithSomething:(id)something
{
[self release]; // don't need this line for ARC
self = nil;
return [[PrivateSubClass alloc] initWithSomething:something];
}
and it if very often to implement init as a factory method. e.g. NSArray, NSDictionary, NSString
As gaige said, it will be much more clearer if you post a piece of code rather than explanations.
Anyway, you can move your factory to the class method, so you will have no such problem at all. I mean something like this:
MyClass* instance = [MyClass instanceWithParameters:params];
#interface MyClass
+ (MyClass*) instanceWithParameters:(ParamType)params;
#end
Without knowing what is the code that is causing the analyzer's behavior it's hard to tell, but as a general rule, here's a couple of compiler-friendly ways to define init/factory methods.
Classic alloc/init
- (instancetype)initWithParameter:(id)parameter {
if(self = [super init]) {
_parameter = parameter;
}
return self;
}
Usage
MyCustomClass * myInstance = [[MyCustomClass alloc] initWithParameter:foo];
This will produce an instance with a +1 retain count. Under ARC this will be automatically managed properly since it follows the NARC rule (New, Alloc, Retain, Copy).
For the same reason, in pre-ARC environments it has to be explicitly released by the client.
Custom factory method
ARC
+ (instancetype)canIHazInstanceWithParameter:(id)parameter {
return [[self alloc] initWithParameter:parameter]; // assuming -initWithParameter: defined
}
Pre-ARC
+ (instancetype)canIHazInstanceWithParameter:(id)parameter {
return [[[self alloc] initWithParameter:parameter] autorelease]; // assuming -initWithParameter: defined
}
Usage
MyCustomClass * myInstance = [MyCustomClass canIHazInstanceWithParameter:foo];
Both in ARC and pre-ARC the method returns an autoreleased instance (this is clearly more explicit in the pre-ARC implementation), which doesn't have to be managed by the client.
Remarks
You may have noticed the instancetype keyword. That's a handy language extension introduced by Clang, that turns the compiler into a dear friend when implementing your own constructors/factory methods. I wrote an article on the subject, which may be relevant to you.
Whether factory methods are preferable to init methods is debatable. From a client perspective it does not make much difference under ARC, provided that you carefully follow the naming conventions, even though I personally tend to expose factory methods in the interface, while implementing custom init methods only internally (as I did in the examples above). It's more a matter of style than an actual practical concern.

Detected autorelease objects

I using Test Driven Development in Objective-C for iOS and Mac OS X development, and I want to be able to write tests that can verify that objects I create with class factory methods return autorelease objects.
How can someone write a test that verifies a provided object is autorelease?
In short, you can't. There is no way to know the autorelease state of an object.
In some cases, you can infer whether an object was placed in an autorelease pool. The idea is declaring a pointer to an object, instantiating it within an #autoreleasepool block, and then verifying that it had dealloc called after the end of the block.
Through whatever combination of swizzling or overriding dealloc you choose, you must first provide a way to verify that dealloc has been called. I wrote an NSObject category with the following interface and implementation, that provides a deallocationDelegate property that will receive a message of handleDeallocation: when the object is deallocated.
#interface NSObject (FunTimes)
#property (nonatomic, assign) id deallocationDelegate;
#end
#implementation NSObject (FunTimes)
+ (void)load
{
Class klass = [NSObject class];
SEL originalSelector = #selector(dealloc);
Method originalMethod = class_getInstanceMethod(klass, originalSelector);
SEL replacementSelector = #selector(funDealloc);
Method replacementMethod = class_getInstanceMethod(klass, replacementSelector);
if(class_addMethod(klass, originalSelector, method_getImplementation(replacementMethod), method_getTypeEncoding(replacementMethod)))
{
class_replaceMethod(klass, replacementSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod));
}
else
{
method_exchangeImplementations(originalMethod, replacementMethod);
}
}
- (void)funDealloc
{
if (self.deallocationDelegate)
[self.deallocationDelegate performSelector:#selector(handleDeallocation:) withObject:self];
[self funDealloc];
}
static char myKey;
- (void)setDeallocationDelegate:(id)deallocationDelegate
{
objc_setAssociatedObject(self, &myKey, deallocationDelegate, OBJC_ASSOCIATION_ASSIGN);
}
- (id)deallocationDelegate
{
return objc_getAssociatedObject(self, &myKey);
}
#end
I ran some test code in my application delegate just to see if it works. I declared an NSMutableArray instance designed to hold NSValue instances derived from the pointers of objects calling -handleDeallocation, which I implement as shown:
- (void)handleDeallocation:(id)toDie
{
NSValue *pointerValue = [NSValue valueWithPointer:toDie];
[self.deallocatedPointerValues addObject:pointerValue];
}
Now, here's a snippet of what I ran. SomeClass is an NSObject subclass with no additional properties or methods.
self.deallocatedPointerValues = [NSMutableArray array];
SomeClass *arsc = nil;
#autoreleasepool {
arsc = [[[SomeClass alloc] init] autorelease];
arsc.deallocationDelegate = self;
NSValue *prePointerValue = [NSValue valueWithPointer:arsc];
BOOL preDeallocated = [self.deallocatedPointerValues containsObject:prePointerValue];
NSLog(#"PreDeallocated should be no is %d",preDeallocated);
}
NSValue *postPointerValue = [NSValue valueWithPointer:arsc];
BOOL postDeallocated = [self.deallocatedPointerValues containsObject:postPointerValue];
NSLog(#"Post deallocated should be yes is %d",postDeallocated);
In this case, it can be verified that the object pointed to by arsc (which stands for auto released SomeClass) has been deallocated due to ending the #autoreleasepool block.
There are several significant limitations to the this approach. One, this cannot work when other messages of retain may be sent to your object that is returned from your factory method. Also, and this should go without saying, swizzling dealloc should only be done in experimental settings, and I think some would argue that it shouldn't be swizzled in testing (obviously it shouldn't be swizzled in production!). Finally, and more significantly, this doesn't work well with Foundation objects such as NSString that have been optimized in ways that it's not always clear whether you are creating a new instance or not. So this is most appropriate, if at all, for your own custom objects.
As a final word, I don't think it's practical to do this really. I felt it was more work than it was worth and is so narrowly applicable as the make spending time learning instruments better to be a far better investment when it comes to memory management. And, of course, with ARC's ascendency, this approach is archaic from the start. Regardless, if you do have need to write such tests, and can work around the limitations here, feel free to adapt this code. I'd be curious to see how it pans out in an actual testing environment.
I commend your dedication to TDD. But memory management is an area where you simply have to follow well-established conventions: "When returning an object, it needs to take care of its own lifetime." My unit tests catch me when I accidentally over-release something, but they won't catch a leak. For that, I rely first on Analyze, then on running the Leaks instrument.

singleton in multi document

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.

singleton in objective c

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];

Setting up NSMutableArray - Can someone explain what this code snippet does?

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