Calling singleton class throw EXC_BAD_ACCESS - objective-c

There is a strange behavior in my code and I really don't know how to solve it.
I have a Singleton class with this definition:
AppModelLocator.h>
#import <Foundation/Foundation.h>
#interface AppModelManager : NSObject
+ (AppModelManager *)sharedManager;
#end
AppModelLocator.m
#import "AppModelManager.h"
static AppModelManager *instance = nil;
#implementation AppModelManager
#pragma mark - Singletone
#pragma mark
+ (AppModelManager *)sharedManager
{
#synchronized ([AppModelManager class]) {
if (instance == nil) {
instance = [AppModelManager new];
}
}
return instance;
}
+ (id)alloc
{
#synchronized ([AppModelManager class]) {
NSAssert(instance == nil, #"Attempted to allocate the second instance of AppModelManager.");
instance = [super alloc];
return instance;
}
return nil;
}
#end
When I call [AppModelLocator sharedManager]somewhere in my code everything is fine. But when I call the singleton class after a specific line of code it throws me EXC_BAD_ACCESS (code=1, address=0xfffffeec) and refers to return instance in sharedManager definition in the singleton class.
That specific code is initializing a class that create a HTTP request and start sending the request but in the class is not any reference of AppModelLocator or something special. It is a simple creating of NSURLConnection and its delegate methods.
I used similar classes and approach in other applications and they are working fine and I wonder what is wrong with this class. I tried a dozen other ways of creating singleton class but none of them were useful.

Why don't you simply use GCD to instantiate your singleton?
+ (AppModelManager *)sharedManager
{
static AppModelManager* instance;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
instance = [[AppModelManager alloc] init];
});
return instance;
}

Finally, I found what was wrong in the code. I made a NSURL instance dynamically and I used 3rd library to encrypt the URL. Something through the encoding caused the crash in special condition but I wonder why the exception raised after calling the singleton class. Anyway the issue was not because of the singleton definition as deanWombourne said.

Related

How do you call a singleton class method from Objective C in a Swift class?

I have the following objective C code which I need to get into a Swift class :
In Logger.m -
+ (Logger *) log
{
static Logger *sharedLog = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedLogger = [[self alloc] init];
});
return sharedLogger;
}
- (void) printString:(NSString *) s
{
NSLog(s)
}
Which is in Logger.h as -
+ (Logger *) log;
- (void) printString:(NSString *) s;
Now, I have this code bridged in to Swift Project - LoggerUserApp where I'm trying to use the above print method from the singleton log shared class method.
I've tried -
Logger.log().printString("String") // Compiler Error. Use Object Construction Logger()
Logger().log().printString("String") // Compiler Error.
Logger().log.printString("String") // Compiler Error.
Logger.printString("String") // This does not call log
Can someone tell me what might be going wrong?
If the Swift compiler mistakenly identifies a method as a class factory method, you can use the NS_SWIFT_NAME macro, passing the Swift signature of the method to have it imported correctly. For example:
+ (id)recordWithQuality:(double)quality NS_SWIFT_NAME(record(quality:));
so,your method should be this:
+ (Logger *) log NS_SWIFT_NAME(log());
I can't reproduce your example completely, but at first sight, this should work:
Logger.log().printString("String")
Since your Obj-C singleton is a function returning the singleton (hence Logger.log() will return your singleton.
But since in your example code I see Logger and then PALog I can't say if this is all you need.
There are some other errors in your example: sharedLog and than sharedLogger.
Here is an example that should work:
Logger.h
#interface Logger : NSObject
+ (Logger *) log;
- (void) printString:(NSString *) s;
#end
Logger.m
#import "Logger.h"
#implementation Logger
+ (Logger *) log
{
static Logger *sharedLog = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedLog = [[self alloc] init];
});
return sharedLog;
}
- (void) printString:(NSString *) s
{
NSLog(#"%#", s);
}
#end
...-Bridging-Header.h
#import "Logger.h"
ViewController.swift
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
Logger.log().printString("Hello")
}
}
In the Swift update, if the class method's name is similar to the class name, then it just takes that as a custom initializer. Now since there was no parameter in the method, it wouldn't come up as the default initializer would come up instead.
Hence, to solve this problem, I had to change the name of the class method log to something different like newLog... and it worked fine.
Logger.newLog().printString("")

No Visible # interface fro 'NSObject', declares the selector 'alloc'

I'm trying to create a singleton. This group of code is meant to establish a settingsMAnager singleton.
Im trying to allocate it but keep throwing an error
Its throwing the error no visible # interface with NSObject.
Declares the selector 'alloc'
Can someone see what's wrong?
Thanks in advance!
//In my .h file I have
+(settingsManager*)getInstance;
-(void)printSettings;
//In My .m file is----
static settingsManager *theInstance = nil;
//Instance Method
+(settingsManager*)getInstance
{
(theInstance == nil)
{
[[self alloc] init];//Im getting "expression result unused" here
}
return theInstance;
}
-(id)alloc
{
theInstance = [super alloc];<------//getting the big error here
return theInstance;
}
-(id)init
{
if (self = [super init])
{
}
return self;
}
(void)printSettings
{
NSLog(#"Hello");
}
You should never subclass the alloc method. Below is the code to use a singleton:
+ (instancetype)sharedInstance {
static SettingsManager *sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [[settingsManager alloc] init];
});
return sharedInstance;
}
And if you're interested in some more reading, I suggest you this link.
I'd also suggest you to read the recommended coding guidelines for objective-c.
instancetype
instancetype is a contextual keyword that can be used as a result type to signal that a method returns a related result type. instancetype, unlike id, can only be used as the result type in a method declaration. More details here.
dispatch_once
As explained here, dispatch_once() is synchronous and allows you to execute a piece of code only once.
This is not the right way to implement a singleton. There are a number of unidiomatic and potentially risky bits in your implementation. However, this error is coming from the fact that alloc is a class method, not an instance method as you've written it here.

Singleton confusion in Objective-C

Consider this code:
+(id)sharedInstance
{
static dispatch_once_t pred;
static MyClass *sharedInstance = nil;
dispatch_once(&pred, ^{
sharedInstance = [[MyClass alloc] init];
});
return sharedInstance;
}
If I follow this singleton design pattern I can make the following assumptions:
The allocation and initialization will only be executed once thanks
to GCD.
The sharedInstance class variable can only be accessed from
within this implementation and shared among the class regardless of the instance.
First time I create the instance I would do something like:
MyClass *something = [MyClass sharedInstance];
my question is, If I call the previews code again but like this:
MyClass *somethingOther = [MyClass sharedInstance];
I can only think of one outcome.
Outcome:
static MyClass *sharedInstance = nil;
Makes sharedInstance class variable point to nil and a nil is returned so somethingOther will be nil.
But I thought that what was supposed to happen in a singleton is that the shared instance would be returned instead.
Now consider this code:
+ (MotionManagerSingleton*)sharedInstance {
static MotionManagerSingleton *_sharedInstance;
if(!_sharedInstance) {
static dispatch_once_t oncePredicate;
dispatch_once(&oncePredicate, ^{
_sharedInstance = [[super allocWithZone:nil] init];
});
}
return _sharedInstance;
}
+ (id)allocWithZone:(NSZone *)zone {
return [self sharedInstance];
}
- (id)copyWithZone:(NSZone *)zone {
return self;
}
Here the
static MotionManagerSingleton *_sharedInstance;
Doesnt set my variable to nil, but i thought that all object pointers are initialized to nil by default.
My question is, how are these class methods returning the "sharedInstance"?
Thanks
One. Non-initialized pointers are non-initialized.
static MotionManagerSingleton *_sharedInstance;
won't make your MotionManagerSingleton point to nil. It will point to an undefined (garbage) location.
Two. Variables declared static are initialized only once (yes, the syntax is a bit inconsistent with the semantics), so your first implementation won't null out the returned shared instance. That's a perfectly fine implementation.

How do I implement an Objective-C singleton that is compatible with ARC?

How do I convert (or create) a singleton class that compiles and behaves correctly when using automatic reference counting (ARC) in Xcode 4.2?
In exactly the same way that you (should) have been doing it already:
+ (instancetype)sharedInstance
{
static MyClass *sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [[MyClass alloc] init];
// Do any other initialisation stuff here
});
return sharedInstance;
}
if you want to create other instance as needed.do this:
+ (MyClass *)sharedInstance
{
static MyClass *sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [[MyClass alloc] init];
// Do any other initialisation stuff here
});
return sharedInstance;
}
else,you should do this:
+ (id)allocWithZone:(NSZone *)zone
{
static MyClass *sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [super allocWithZone:zone];
});
return sharedInstance;
}
This is a version for ARC and non-ARC
How To use:
MySingletonClass.h
#interface MySingletonClass : NSObject
+(MySingletonClass *)sharedInstance;
#end
MySingletonClass.m
#import "MySingletonClass.h"
#import "SynthesizeSingleton.h"
#implementation MySingletonClass
SYNTHESIZE_SINGLETON_FOR_CLASS(MySingletonClass)
#end
This is my pattern under ARC.
Satisfies new pattern using GCD and also satisfies Apple's old instantiation prevention pattern.
#implementation AAA
+ (id)alloc
{
return [self allocWithZone:nil];
}
+ (id)allocWithZone:(NSZone *)zone
{
[self doesNotRecognizeSelector:_cmd];
abort();
}
+ (instancetype)theController
{
static AAA* c1 = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^
{
c1 = [[super allocWithZone:nil] init];
// For confirm...
NSLog(#"%#", NSStringFromClass([c1 class])); // Prints AAA
NSLog(#"%#", #([c1 class] == self)); // Prints 1
Class real_superclass_obj = class_getSuperclass(self);
NSLog(#"%#", #(real_superclass_obj == self)); // Prints 0
});
return c1;
}
#end
Read this answer and then go and read the other answer.
You must first know what does a Singleton mean and what are its requirements, if you don't understand it, than you won't understand the solution--at all!
To create a Singleton successfully you must be able to do the following 3:
If there was a race condition, then we must not allow multiple instances of your SharedInstance to be created at the same time!
Remember and keep the value among multiple invocations.
Create it only once. By controlling the entry point.
dispatch_once_t helps you to solve a race condition by only allowing its block to be dispatched once.
Static helps you to “remember” its value across any number of
invocations. How does it remember? It doesn't allow any new instance with that exact name of your sharedInstance to be created again it just works with the one that was created originally.
Not using calling alloc init (i.e. we still have alloc init methods since we are an NSObject subclass, though we should NOT use them) on our sharedInstance class, we achieve this by using +(instancetype)sharedInstance, which is bounded to only be initiated once, regardless of multiple attempts from different threads at the same time and remember its value.
Some of the most common system Singletons that come with Cocoa itself are:
[UIApplication sharedApplication]
[NSUserDefaults standardUserDefaults]
[NSFileManager defaultManager]
[NSBundle mainBundle]
[NSOperations mainQueue]
[NSNotificationCenter defaultCenter]
Basically anything that would need to have centralized effect would need to follow some sort of a Singleton design pattern.
Alternatively, Objective-C provides the +(void)initialize method for NSObject and all its sub-classes. It is always called before any methods of the class.
I set a breakpoint in one once in iOS 6 and dispatch_once appeared in the stack frames.
Singleton Class : No one can create more than one object of class in any case or through any way.
+ (instancetype)sharedInstance
{
static ClassName *sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [[ClassName alloc] init];
// Perform other initialisation...
});
return sharedInstance;
}
// You need need to override init method as well, because developer can call [[MyClass alloc]init] method also. that time also we have to return sharedInstance only.
-(MyClass)init
{
return [ClassName sharedInstance];
}
There are two issues with the accepted answer, which may or may not be relevant for your purpose.
If from the init method, somehow the sharedInstance method is called again (e.g. because other objects are constructed from there which use the singleton) it will cause a stack overflow.
For class hierarchies there is only one singleton (namely: the first class in the hierarchy on which the sharedInstance method was called), instead of one singleton per concrete class in the hierarchy.
The following code takes care of both of these problems:
+ (instancetype)sharedInstance {
static id mutex = nil;
static NSMutableDictionary *instances = nil;
//Initialize the mutex and instances dictionary in a thread safe manner
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
mutex = [NSObject new];
instances = [NSMutableDictionary new];
});
id instance = nil;
//Now synchronize on the mutex
//Note: do not synchronize on self, since self may differ depending on which class this method is called on
#synchronized(mutex) {
id <NSCopying> key = (id <NSCopying>)self;
instance = instances[key];
if (instance == nil) {
//Break allocation and initialization into two statements to prevent a stack overflow, if init somehow calls the sharedInstance method
id allocatedInstance = [self alloc];
//Store the instance into the dictionary, one per concrete class (class acts as key for the dictionary)
//Do this right after allocation to avoid the stackoverflow problem
if (allocatedInstance != nil) {
instances[key] = allocatedInstance;
}
instance = [allocatedInstance init];
//Following code may be overly cautious
if (instance != allocatedInstance) {
//Somehow the init method did not return the same instance as the alloc method
if (instance == nil) {
//If init returns nil: immediately remove the instance again
[instances removeObjectForKey:key];
} else {
//Else: put the instance in the dictionary instead of the allocatedInstance
instances[key] = instance;
}
}
}
}
return instance;
}
#import <Foundation/Foundation.h>
#interface SingleTon : NSObject
#property (nonatomic,strong) NSString *name;
+(SingleTon *) theSingleTon;
#end
#import "SingleTon.h"
#implementation SingleTon
+(SingleTon *) theSingleTon{
static SingleTon *theSingleTon = nil;
if (!theSingleTon) {
theSingleTon = [[super allocWithZone:nil] init
];
}
return theSingleTon;
}
+(id)allocWithZone:(struct _NSZone *)zone{
return [self theSingleTon];
}
-(id)init{
self = [super init];
if (self) {
// Set Variables
_name = #"Kiran";
}
return self;
}
#end
Hope above code will help it out.
if you need to create singleton in swift,
class var sharedInstance: MyClass {
struct Singleton {
static let instance = MyClass()
}
return Singleton.instance
}
or
struct Singleton {
static let sharedInstance = MyClass()
}
class var sharedInstance: MyClass {
return Singleton.sharedInstance
}
you can use this way
let sharedClass = LibraryAPI.sharedInstance

Objective C - Category to modify a singleton object?

I know that the whole point of singleton is to instantiate 1 instance of the onject and reuse it, but when it comes to unit testing I want to be able to renew the singleton object before every test.
I tried to use a category to access the singleton object and release it but It's not accessible by categories any idea what's the best way to achieve this?
#implementation SingletonClass
static SingletonClass *singleton;
+ (SingletonClass*)sharedInstance
{
if (!singleton)
{
singleton = [[SingletonClass alloc] init];
}
return singleton;
}
#end
.
#implementation SingletonClass(Unit Testing Additions)
+ (void)killInstance
{
// I get an error here and I cannot access the singleton Object
[singleton release], singleton = nil;
}
#end
By the very definition of singleton, you can't do this.
If it is your class, don't make it a singleton.
If it isn't your class, doing this will fail.
I'm not sure whether this will work, but maybe you could just override the sharedInstance class method and manage the singleton yourself:
#implementation SingletonClass (Unit Testing Additions)
static SingletonClass *myVeryOwnSharedInstance;
+ (SingletonClass *) sharedInstance
{
if (!myVeryOwnSharedInstance)
myVeryOwnSharedInstance = [[self alloc] init];
return myVeryOwnSharedInstance;
}
+ (void) killInstance
{
[myVeryOwnSharedInstance release];
// if release is overridden to do no-op, maybe just invoke -dealloc directly
myVeryOwnSharedInstance = nil;
}
#end
If you want access to your singleton global variable outside of the file in which it's declared, you'll need to make it globally accessible using extern.
At the top of SingletonClass.h, put this:
extern SingletonClass *singletonClassSingleton;
In your SingletonClass.m, use this:
SingletonClass *singletonClassSingleton = nil;
Then assuming you have #import "SingletonClass.h" in your unit test .m file, you should be able to add:
#implementation SingletonClass(Unit Testing Additions)
+ (void)killInstance
{
[singletonClassSingleton release], singletonClassSingleton = nil;
}
#end
The reason I've renamed singleton to singletonClassSingleton is that the variable is now global - if you have a bunch of singleton classes, you need these variables to have unique names, like dataManagerSingleton, resourceManagerSingleton or whatever.
Here is my own solution.
#implementation SingletonClass(Unit Testing Additions)
//Override
static SingletonClass *singleton;
+ (void)killInstance
{
// I get an error here and I cannot access the singleton Object
[singleton release], singleton = nil;
}
//Override
+ (SingletonClass*)sharedInstance
{
if (!singleton)
{
singleton = [[SingletonClass alloc] init];
}
return singleton;
}
#end