IOS7 Singleton Object Bad Access Code 1 - objective-c

(CODE UPDATED) after IOS 7 update, my app is crashing with singleton label (and this happened only in the device)...first time accessing singleton everything it's ok, but second time ClassSingleton is nil. Can anyone help? (before IOS 7 everything was fine...now i get Bad Access Code =1)
I'm using ARC...
thanks
ClassSingleton.h
#property (nonatomic, strong) IBOutlet UILabel *lblResultado;
ClassSingleton.m
#synthesize lblResultado;
__strong static ClassSingleton *pOutClassSingletonReturn = nil;
#pragma mark Singleton Methods
+ (void)initialize
{
pOutClassSingletonReturn = [[super allocWithZone:NULL] init];
pOutClassSingletonReturn.lblResultado = [[UILabel alloc] init];
pOutClassSingletonReturn.lblResultado.backgroundColor = [UIColor clearColor];
pOutClassSingletonReturn.lblResultado.textColor = [UIColor whiteColor];
pOutClassSingletonReturn.lblResultado.textAlignment = NSTextAlignmentRight;
pOutClassSingletonReturn.lblResultado.text = #"0";
}
+ (ClassSingleton*) pOutClassSingletonReturn
{
return pOutClassSingletonReturn;
}
#end
AccessClass.m
#implementation AccessClass
__strong static ClassSingleton *pOutClassSingletonReturn;
- (void)viewDidLoad
{
[super viewDidLoad];
externalsObjects = [NSDictionary dictionaryWithObject:[ClassSingleton pOutClassSingletonReturn] forKey:#"pOutClassSingletonReturn"];
nibOptions = [NSDictionary dictionaryWithObject:externalsObjects forKey:UINibExternalObjects];
[self.nibBundle loadNibNamed:self.nibName owner:self options:nibOptions];
pOutClassSingletonReturn = [ClassSingleton pOutClassSingletonReturn];
pOutClassSingletonReturn.lblResultado.text = #"1";
}
- (IBAction) button: (id) sender
{
pOutClassSingletonReturn.lblResultado.text = #"blabla"; //==>>> Crash second time i press the button
}

You implemented the singleton pattern improperly in modern Objective-C.
In this example, let's call your Singleton class method, sharedInstance. Initialize your singleton as follows:
+ (id)sharedInstance
{
static id sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [[self alloc] init];
});
return sharedInstance;
}
Then, in the same Singleton Class, put your initialization code in your init method
- (id)init
{
self = [super init];
if (self) {
// Your initialization code goes here
}
return self;
}
You can change the method from init to whatever you want. Just make sure to change the name in the sharedInstance class method.
To call your Singleton in your other classes, simply do the following:
[MySingletonClass sharedInstance]
The first time it's called, the init method in the Singleton will be set (which is obvious, as it's a Singleton).

Try initializing your singleton using the static + (void)initialize method instead.
See: What should my Objective-C singleton look like?

I don't see where you've declared pOutClassSingletonReturn in AccessClass.m, so it's hard to tell if it's a global variable, an instance variable, a reference to the pOutClassSingletonReturn in ClassSingleton.m, or what. But I suspect that the problem isn't so much with the pOutClassSingletonReturn in ClassSingleton.m as it is with the one in AccessClass.m. Make sure that's a strong reference, or at least add it to your view hierarchy in -viewDidLoad.

First i want to thanks to everyone who try to help!
I found the error (singleton was ok...)...the error was
when i concatenate 2 NSString's like that i get an error (further in the singleton):
pOutclassCalculadora.pstrOutParcela1 = [pOutclassCalculadora.pstrOutParcela1 stringByAppendingString: pOutclassCalculadora.pstrOutTeclaSender];
Now i'm doing like that and everything is ok (no bad access):
pOutclassCalculadora.pstrOutParcela1 = [NSString stringWithFormat:#"%#%#",pOutclassCalculadora.pstrOutParcela1,pOutclassCalculadora.pstrOutTeclaSender];
The big question...why this "stringByAppendingString" works in the simulator and in IO6 and crashes in IOS7 (and only in the device)?????

If you are using ARC then try declaring the static to be strong like this:
__strong static ClassSingleton *pOutClassSingletonReturn = nil;
so that ARC knows to retain it for you.

Related

Singleton set in AppDelegate loses it value when allocated in another class

I have a iPad application where I'm attempting to use a singleton. This is the code in the .h file:
//-------------------------------------------
//-- singleton: timeFormat
#interface SingletonTimeFormat : NSObject {
}
#property (nonatomic, retain) NSNumber *timeFormat;
+ (id)sharedTimeFormat;
#end
This is the code from the .m file:
//-------------------------------------------
//-- SingletonTimeFormat
#implementation SingletonTimeFormat {
}
#synthesize timeFormat;
//-- sharedColorScheme --
+ (id)sharedTimeFormat {
static dispatch_once_t dispatchOncePredicate = 0;
__strong static id _sharedObject = nil;
dispatch_once(&dispatchOncePredicate, ^{
_sharedObject = [[self alloc] init];
});
return _sharedObject;
}
-id) init {
self = [super init];
if (self) {
timeFormat = [[NSNumber alloc] init];
}
return self;
}
#end
I load the value (either 12 or 24) in AppDelegate - didFinishLaunchingWithOptions, then when I want to get the value of timeFormat I use this:
SingletonTimeFormat *stf = [[SingletonTimeFormat alloc]init];
if([stf.timeFormat isEqualToNumber: [NSNumber numberWithInt:12]]) {
which returns 0 (it was set correctly in AppDelegate, but apparently when I do the alloc in another class, it loses it's value. So obviously it's not working! (I have several other singletons that have the same pattern, but so far they appear to be working.
What's wrong here and how do I fix it?
You don't want to call your singleton using alloc init. With this singleton, all references to it should be through its sharedTimeFormat method, which will init the object if necessary, and will return the singleton instance otherwise.
In other words, it doesn't appear that you're referencing the instance of the object stored in the static sharedObject variable, which means that it's stored value will not necessarily be the same.

short call for singleton

Update with working code. Problem was like #HotLinks state, that I did init instead of initWithBaseURL:url
I am using a Singleton in my App, based on this guide.
Now every time I use the singleton I do like this:
SingletonClass* sharedSingleton = [SingletonClass sharedInstance];
[sharedSingleton callAMethod];
// or
[[SingletonClass sharedInstance] callAMethod];
Is there a way to use a short syntax, especially if I have to use the Singleton several times? Something like:
[sc callAMethod];
I tried already this kind, but it did not work, as the init method was not called...
WebApi.h
#import "AFHTTPRequestOperationManager.h"
#import "SingletonClass.h"
#interface WebApi : AFHTTPRequestOperationManager
#property (nonatomic, strong) SingletonClass *sc;
+(WebApi*)sharedInstance;
-(void)sandbox;
#end
WebApi.m (updated with working code)
#import "WebApi.h"
#implementation WebApi
//-(WebApi*)init {
-(WebApi*)initWithBaseURL:url {
self = [super init];
if (self != nil) {
self.sc = [SingletonClass sharedInstance]; // is never called.
}
return self;
}
#pragma mark - Singleton methods
/**
* Singleton methods
*/
+(WebApi*)sharedInstance
{
static WebApi *sharedInstance = nil;
static dispatch_once_t oncePredicate;
dispatch_once(&oncePredicate, ^{
sharedInstance = [[self alloc] initWithBaseURL:[NSURL URLWithString:kApiHost]];
});
return sharedInstance;
}
-(void)sandbox {
DLog(#"test short singleton call: %#", [sc callAMethod];
}
#end
Debug Message
[WebApi sandbox] [Line 42] test short singleton call: (null)
I don't see how you can do this in any language. In Java, you would generally see
<Class>.getInstance().<blah>.
There's nothing stopping you from getting that instance inside a method where it will be used a lot, e.g.
WebApi *api = [WebApi sharedInstance];
then a whole lot of:
[api <method1>];
...
Does that get you there?
(Amusingly, a developer and I were discussing this issue yesterday because the example code Apple has for use of the accelerometer puts the motion manager in the app delegate and the syntax to get a hold of the manager is completely insane:
CMMotionManager *mManager = [(APLAppDelegate *)[[UIApplication sharedApplication] delegate] sharedManager];
As you can see, they are making a local var and then diddling that from there on in the controller class.
You could declare a global variable and set it in your +sharedInstance method, then make sure you call +sharedInstance once.
But, really, don't bother. Using [SomeClass sharedInstance] makes it easy to quantify all uses of shared instances in your code base, as well as all uses of SomeClass's class level API. Both are quite useful for anyone else that ends up maintaining your code.
Secondly, it doesn't really save that much typing. Not enough to justify requiring everyone to learn about a new global.
(What Rob said):
Finally, if you are calling instance methods on the shared instance repeatedly in a scope, just use a local variable:
ThingManager *thingManager = [ThingManager sharedInstance];
[thingManager foo];
[thingManager bar];
[thingManager baz];
You can do it this way:
In .h file
#interface WebApi : AFHTTPRequestOperationManager
#property (nonatomic, strong) SingletonClass *sc;
...
+(id) methodName;
...
#end
In .m file
+(id) methodName
{
return [[WebApi shareInstance] instanceMethod];
}
- (id) instanceMethod
{
return #"SMTH";
}

Why is my NSMutableArray, located in a singleton, returning (null)?

I am working in Xcode 4.5.1 in Objective-C. I’m making a hearing test and want to store relevant data to each question in an array. I made a singleton MyManager. I use this to store data.
It is working fine for simple int/float values etc., but I’m stuck trying to use NSMutableArray. I’m new to Objective-C, so I’m assuming/hoping I've made some obvious mistake.
So, I want to fill mySNRArray with float values. I’ve come to understand that I can’t simply add floats, because it will only take objects. Thus, I use NSNumber.
Problem: When I try to read the data that I’ve supposedly added to the NSMutableArray, I get (null).
I will now provide the relevant code:
MyManager.h
#interface MyManager : NSObject
{
NSMutableArray *mySNRArray;
}
#property (readwrite) NSMutableArray *mySNRArray;
+ (id)sharedManager;
#end
MyManager.m
#implementation MyManager
#synthesize mySNRArray;
+ (id)sharedManager
{
static MyManager *sharedMyManager = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^
{
sharedMyManager = [[self alloc] init];
});
return sharedMyManager;
}
- (id)init
{
if (self = [super init])
{
NSMutableArray *mySNRArray = [[NSMutableArray alloc]init];
}
return self;
}
#end
TestViewController.m
//First, I try to add a value to mySNRArray.
MyManager *Manager = [MyManager sharedManager];
NSNumber *tempStorage1 = [[NSNumber alloc] initWithFloat:mySNR];
[Manager.mySNRArray insertObject:tempStorage1 atIndex:questionNumber];
//The NSLog below is showing the correct value.
NSLog(#"%# : mySNR", tempStorage1);
...
for (n = 0; n < questionNumber; n++)
{
//Second, I try to acces the values I supposedly added to mySNRArray.
MyManager *Manager = [MyManager sharedManager];
//This NSLog below is showing (null).
NSLog(#"Value at %i in SNRArray = %#", n, [Manager.mySNRArray objectAtIndex:n]);
}
...
I hope somebody can explain my error.
change
NSMutableArray *mySNRArray = [[NSMutableArray alloc]init];
to
self->_mySNRArray = [[NSMutableArray alloc]init];
in your init method you are creating a local mutable array, but not assigning it to your property
Instead of creating a new object, use the ivar you created..in the init method.
_mySNRArray = [[NSMutableArray alloc]init];
Even you can ommit these, from your .h
{
NSMutableArray *mySNRArray;
}
+ (id)sharedManager
returns a value
static MyManager* sharedManager
Change the interface to
+ (MyManager*)sharedManager
and the compiler will tell you exactly what mistake you made.

Singleton gets deallocated

I've created a simple singleton class to hold static data for my projects.
The first time I access this singleton is onEnter method in my Cocos2d scene. However when I try to access it again later in another method (same scene) this singleton is already released. I'm confused, how do I keep my singleton from being deallocated?
Here's my singleton's interface part:
#import <Foundation/Foundation.h>
#interface OrchestraData : NSObject
+(OrchestraData *)sharedOrchestraData;
#property (retain, readonly) NSArray *animalNames;
#end
Implementation:
#import "OrchestraData.h"
#implementation OrchestraData
#synthesize animalNames = animalNames_;
+(OrchestraData*)sharedOrchestraData
{
static dispatch_once_t pred;
static OrchestraData *_sharedOrchestraData = nil;
dispatch_once(&pred, ^{ _sharedOrchestraData = [[OrchestraData alloc] init]; });
return _sharedOrchestraData;
}
-(id)init {
if (self = [super init]) {
animalNames_ = [NSArray arrayWithObjects:#"giraffe", #"giraffe", #"giraffe", #"giraffe", nil];
}
return self;
}
#end
I'm using my singleton this way:
[[OrchestraData sharedOrchestraData] animalNames];
Update:
I took a fresh look into it with NSZombies enabled, it appears as if my NSArrays were released, not the singleton itself. What do I do?
You must implement your singleton in this way:
1) in .h file of your Singleton Class:
+ (SingletonClass *)instance;
2) in .m file:
+ (SingletonClass *)instance {
static SingletonClass* instance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
instance = [[self alloc] init];
//your init code here
});
return instance;
}
If you want to call your singleton, just call [SingletonClass instance].
If your are interesting what is "dispatch_once_t", read about Grand Central Dispatch:
http://developer.apple.com/library/ios/#documentation/Performance/Reference/GCD_libdispatch_Ref/Reference/reference.html
RE Update:
Your NSArray deallocates because you're using the autorelease initializer arrayWithObjects and you assign it directly to the ivar animalNames_. Therefore it is not retained.
To fix this, assign the array to the property:
self.animalNames = [NSArray arrayWithObjects:#"giraffe", #"giraffe", #"giraffe", #"giraffe", nil];
Btw, under ARC this wouldn't have been an issue since the ivar would have been a strong (retaining) reference. I don't get tired encouraging anyone to switch to ARC. It's been available for well over a year now and there's absolutely no point in using MRC code anymore! It really pains me to see how developers still don't use the easier, faster, and straightforward option. (rant off) :)
You setup a pointer wherever you need it.
-(void)someMethod {
MySingleton *singleton = [MySingleton sharedSingleton];
singleton.data = YES; //dumb example to show you did something...
}
-(void)someOtherMethod {
MySingleton *singleton = [MySingleton sharedSingleton]; //You have to create a new pointer...
singleton.data = NO; //another dumber example to show you did something...
}
Note: this assumes that you have created a singleton the same way I have... your code might be different therefore causing my answer not to apply...
You need to overwrite the below method inside your singleton class, because in your program, if someone has initialised [[SingletonClass alloc] init] then singleton will have another instance and release it will cause an error.
+ (id)allocWithZone:(NSZone *)zone{
return [[self SingletonClass] retain];
}
- (id)copyWithZone:(NSZone *)zone{
return self;
}
- (id)retain{
return self;
}

Objective-C, class identity

I have the following situation, i can't resolve:
#interface Deck : NSObject
#interface MasterDeck : Deck
#interface PlayerDeck : Deck
Inside MasterDeck class, as part of initialization, i call
[self cutDeckImageIntoCards]; // We don't get to execute this method
Call results in an error [PlayerDeck cutDeckImageIntoCards]: unrecognized selector sent to instance
Indeed, PlayerDeck does not have this method .. but why is it being called at all?
After looking at MasterDeck's initialization i added a few debugging statements:
static MasterDeck *gInstance = NULL;
+(MasterDeck *) instance {
#synchronized(self) {
if (gInstance == NULL) {
gInstance = [[self alloc] init];
}
}
return gInstance;
}
-(id) init {
if (gInstance != NULL) {
return gInstance;
}
// MasterDeck
self = [super init];
// PlayerDeck
if (self) {
// Lots of stuff
[self cutDeckImageIntoCards]
// Some more stuff
}
gInstance = self;
return gInstance;
}
Ok, so MasterDeck is PlayerDeck because' Deck thinks it is a PlayerDeck ... Deck confirms
Deck is created as follows:
static Deck *gInstance = NULL;
+(Deck *) instance {
#synchronized(self) {
if (gInstance == NULL) {
gInstance = [[self alloc] init];
}
}
return gInstance;
}
-(id) init {
if (gInstance != NULL) {
return gInstance;
}
self = [super init];
if (self) {
// Do something
}
NSLog(#"Deck thinks it's a %#", [[self class ]description]); // PlayerDeck
gInstance = self;
return gInstance;
}
So, again
#interface Deck : NSObject
Assuming above Singleton Implementation, why would Deck think it's actually a PlayerDeck?
So the way you've written this, if you create the PlayDeck instance first, then the Deck instance is now a PlayDeck.
And then if you go to create the MasterDeck instance, your call to [super init] dutifully returns that previous PlayDeck instance.
So why is Deck a singleton at all? Deck has two subclasses that are singletons, but are you really looking for a singleton Deck also?
At a minimum, you can make this sort of work by not setting gInstance from within each init. Let the class method do that. Just return self from each of the init's. Also, remove the check for gInstance being not null, other Deck's init will always return Deck's instance once you have an instance of Deck.
But beyond that, I would rethink this idea a bit. Hope that helps.
You'll probably want to separate your singleton class from the actual class.
Try implementing it as in this example,
+(id) instance {
static dispatch_once_t pred;
static MasterDeck *sharedInstance = nil;
dispatch_once(&pred, ^{
sharedInstance = [[MasterDeck alloc] init];
});
return sharedInstance;
}
What happens if you replace [[self alloc] init] with [[MasterDeck alloc] init]?
It may be that somehow self is PlayerDeck. To make sure, you could NSLog([self description]) just before calling + alloc.
Edit
I assume that the interesting part of the code you have above is part of the #implementation of MasterDeck. My suggestion would be to try a lot more logging, including determining what super and [self class] are before calling [super init], although these may be misleading...
Also, as a side note, I believe that you should call [self release] in init if you are returning the previously-created instance.
What does the [super init] method look like? Can you step into it, or is it the default initializer?
Edit 2
I think you're doing singletons wrong. If you initialize a PlayerDeck, that would create a singleton in Deck which is an instance of PlayerDeck. Then later, when you initialize a MasterDeck, calling [super init] will return the instance already created by the PlayerDeck.
It looks like you try to be clever, but fact is - often the computer is even smarter. :)
Your deck class caches an instance in gInstance - in fact, it looks like it may store a Deck, a PlayerDeck, or a MasterDeck, depending on what and how you call / instantiate first. After that, this very instance is returned by that init method.
I strongly suggest to get this code clean and readable. I bet there are numerous problems with this code - but your problem is already a good example. Your logic (which should be simple, I guess) can surely be implemented much easier.
Note - I'm not against singletons, but this sort of code stacking is an absolute no-go. It's hard to get more dependency logic into those lines. ;)