Can't add object to static NSMutableArray - objective-c

I have a static variable on appDelegate declared like this:
appdelegate.h file:
+(NSMutableArray*)allBanco;
+(void)setAllBanco:(NSMutableArray*)value;
appdelegate.m file:
static NSMutableArray * allBanco;
+(NSMutableArray*)allBanco
{
return allBanco;
}
+(void)setAllBanco:(NSMutableArray*)value
{
if(allBanco != value)
{
[allBanco release];
allBanco = [value copy];
}
}
I tried to acess it on other class
on .m file:
#import "AppDelegate.h"
[[AppDelegate allBanco] addObject:testeObj];
i cant understand why,i can log the
NSLog(#"%i",[[AppDelegate allBanco] count]);
and goes ok.
I tried :
NSMutableArray * temp = [[[NSMutableArray alloc]init]autorelease];
temp = [AppDelegate allBanco];
[temp addObject:testeObj];
[AppDelegate setAllBanco:temp];
and doest work.

Considering you created your array properly, keep in mind that -copy returns an immutable copy, so you may crash later when modifying it.
Now that you added your error, I'm quite sure this is indeed the problem:
-[__NSArrayI addObject:]: unrecognized selector sent to instance
You tried to add an object in a NSArray, not a NSMutableArray. Try using -mutableCopy.

You haven't created an object for allBanco to point to. Change your method so that you can create one if it doesn't exist yet:
+(NSMutableArray*)allBanco
{
if (!allBanco)
allBanco = [[NSMutableArray alloc] init];
return allBanco;
}

Related

Why cannot I modify an object inside my method

I am calling an Api asynchronously to get the data. Then I am assigning the data to a shared instance successfully inside a block given below.
RestApiManager *api= [[RestApiManager alloc]init];
[ObjectBuilder sharedManager];
self.obj = [[Object alloc]init];
[api get_data:credential.password finish:^(NSDictionary *data) {
if(data){
self.obj = [ObjectBuilder obj:data];
[[ObjectBuilder sharedManager]setObject:self.obj];
}
This all working as expected except when I try to update some of the values in one of NSMutableDictionary properties of the obj.
- (void)update: (NSInteger) temp {
array3 = [[NSMutableArray alloc]init];
NSNumber *start =[[NSNumber numberWithInteger:var];
[NSNumber numberWithInteger:var2];
NSNumber *temp2 =[NSNumber numberWithInteger:temp];
[array3 addObject:temp2];
[array3 addObject:start];
[array3 addObject:end];
[self.obj.sch setObject:array3 forKey:temp2];
}
[obj.sch setObject:array3 forKey:temp2]; always crashes my app.
Now I have vague idea whats going on, basically I am setting obj inside a block code, whilst in my update function I am trying to change the contents outside block code.
The error I get is
reason: '-[__NSDictionaryI setObject:forKey:]: unrecognized selector sent to instance
Note this error goes away if i declare line
[[ObjectBuilder sharedManager]setObject:obj];
Outside the finish:^ block
But then I lose all the data obtained from api call.
Object is declared as below #interface Object : NSObject
#property (strong, nonatomic) NSMutableDictionary *sch;

message sent to deallocated instance ,,, [__NSArrayI respondsToSelector:]

I have this implementation file with aNSArray object userIDs
NSArray *userIDs;
NSInteger friendID;
#implementation TableViewController
-(void)reciveFriendsIDs:(NSArray *)array
{
userIDs = [NSArray arrayWithArray:array];
}
-(NSString *)getFriendId
{
return [userIDs objectAtIndex:friendID];
}
.
.
.
#end
and the method -(NSString *)getFriendId call it from another class like this :
TableViewController *tableController = [[TableViewController alloc]init];
NSString *fid = [tableController getFriendId];
But I am having an error said "-[__NSArrayI respondsToSelector:]: message sent to deallocated instance 0x20320200" and the compiler indicate the error in this line:
return [userIDs objectAtIndex:friendID];
You are allocating the NSArray with arrayWithArray static method.
In this way it's getting added in the auto release pool and the retain count will be 0.
Either retain it or manually alloc it with [[NSArray alloc] init]
I was getting the same exception on line
if(self.arrTypes != nil)
cause of the following line being used at a different place in code
[self.arrTypes release];
and replacing this code with
self.arrTypes = nil;
resolved the issue.

making NSArray global

i have NSarray which i want to acces from all of my methods,(i want it Global), i m going to populate this array in one of my methods defined in .m file(only once).
my question is ... is it really possible to declare a NSArray in .h and define it place somewhere else or it just has to be defined when it is declared(initialization).
MY CURRENT CODE
.h file
#interface slots2ViewController : UIViewController {
NSArray* paylinesArr;
}
i m calling follwing method from ViewDidLoad
.m file
-(void)init_payline_arr
{
NSString* filePath = #"/Users/net4uonline/Desktop/slots2/paylines.txt";//filepath...
NSString *fileContents = [NSString stringWithContentsOfFile: filePath];
paylinesArr = [fileContents componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]];
}
i m not able to use paylinesArr array from other methods the app crashes if follwing function is getting called
-(IBAction)ShowVal
{
NSLog(#"number of elements! %#",[paylinesArr count]);
}
Or
should i use NSMutabbleArray instead?
if you want to see then i have uploaded my desktop video while i m using debug tools!
the link to video
in this video i press the record button of the debugger(i have ns zombie enabled and the retain count as well),the app starts,i press spin button and apparently it crashes...then i show you the code which has
paylinesArr = [[fileContents componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]] retain];
which retains the paylineArr
NSMutableArray won't help you! The reason of your error is that your paylinesArr variable is autorelease variable, so probably it was deallocated before ShowVal is called. Try to retain it like
-(void)init_payline_arr {
...
paylinesArr = [[fileContents componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]] retain];
...
}
This should work. But don't forget to release it in viewDidUnload method:
- (void)viewDidUnload {
[super viewDidUnload];
...
[paylinesArr release];
}

Objective C Reassignment/Memory Management Crash

As a relative Objective-C beginner, I'm obviously still not grasping certain memory management rules. I can't figure out how to make this not crash:
#interface MyClass { NSArray *playerArray4th; }
- (void) viewDidLoad { playerArray4th = [self getAudioPlayersForSoundFile:#"rimshot" ofType:#"aif"]; }
- (NSArray*) getAudioPlayersForSoundFile:(NSString*)soundFileName ofType:(NSString*)soundFileType {
//code instantiating objects....
NSArray *toRet = [[NSArray alloc] initWithObjects:toRetTickPlayer,toRetTickPlayerCopy,toRetTickPlayerCopy2,toRetTickPlayerCopy3, nil];
return toRet;
}
Then later, in a different function:
NSArray *currentArray = playerArray4th;
[currentArray release];
currentArray = nil;
currentArray = [self getAudioPlayersForSoundFile:fileName ofType:ofType];
And it crashes when trying to access the array again:
- (void) playSound:(NSString*)soundType {
AVAudioPlayer *currentPlayer;
if ([soundType isEqualToString:#"4th"]) {
if (playerArray4thCounter >= [playerArray4th count]) playerArray4thCounter = 0;
NSLog(#"Playing from array: %#",playerArray4th);
currentPlayer = [playerArray4th objectAtIndex:playerArray4thCounter];
playerArray4thCounter++;
}
}
Try to learn about properties and about using getters and setters. Don't take shortcuts unless you know exactly what's going on.
So define the playerArray4th property in your header file:
#property (nonatomic,retain) NSArray *playerArray4th;
And then in your .m file create getter/setter:
#synthesize playerArray4th;
Then, always use self.playerArray4th for assigning and getting the variable. The prior objects will be released when needed.
So this will not leak:
self.playerArray4th = [NSArray arrayWithObjects:#"text",#"text",nil];
self.playerArray4th = [NSArray arrayWithObjects:#"new array",#"text",nil];
because the second assignment releases the first array.
Furthermore, read about using autorelease. In short, if you alloc, copy or new, you should either release or autorelease. There's a lot to read about this here on SO which I will not repeat here now.
Don't forget to put self.playerArray4th = nil; in your dealloc method.

Singleton EXC_BAD_ACCESS

so I have a class that I declare as a singleton and in that class I have a NSMutableArray that contains some NSDictionaries with some key/value pairs in them. The trouble is it doesn't work and I don't know why... I mean it crashes with EXC_BAD_ACCESS but i don't know where. I followed the code and it did create a new array on first add, made it to the end of the function ..and crashed ...
#interface dataBase : NSObject {
NSMutableArray *inregistrari;
}
#property (nonatomic,retain) NSMutableArray *inregistrari;
-(void)adaugaInregistrareCuData:(NSDate *)data siValoare:(NSNumber *)suma caVenit:(BOOL)venit cuDetaliu:(NSString *)detaliu;
-(NSDictionary *)raportIntreData:(NSDate *)dataInitiala siData:(NSDate *)dataFinala;
-(NSArray *)luniDisponibileIntreData:(NSDate *)dataInitiala siData:(NSDate *)dataFinala;
-(NSArray *)aniDisponibiliIntreData:(NSDate *)dataInitiala siData:(NSDate *)dataFinala;
-(NSArray *)vectorDateIntreData:(NSDate *)dataI siData:(NSDate *)dataF;
-(void)salveazaInFisier;
-(void)incarcaDinFisier;
+ (dataBase *)shareddataBase;
#end
And here is the .m file
#import "dataBase.h"
#import "SynthesizeSingleton.h"
#implementation dataBase
#synthesize inregistrari;
SYNTHESIZE_SINGLETON_FOR_CLASS(dataBase);
-(void)adaugaInregistrareCuData:(NSDate *)data siValoare:(NSNumber *)suma caVenit:(BOOL)venit cuDetaliu:(NSString *)detaliu{
NSNumber *v=[NSNumber numberWithBool:venit];
NSArray *input=[NSArray arrayWithObjects:data,suma,v,detaliu,nil];
NSArray *keys=[NSArray arrayWithObjects:#"data",#"suma",#"venit",#"detaliu",nil];
NSDictionary *inreg=[NSDictionary dictionaryWithObjects:input forKeys:keys];
if(inregistrari == nil) {
inregistrari=[[NSMutableArray alloc ] initWithObjects:inreg,nil];
}else {
[inregistrari addObject:inreg];
}
[inreg release];
[input release];
[keys release];
}
It made it to the end of that adaugaInregistrareCuData ... ok . said the array had one object ... and then crashed
Try adding "NSZombieEnabled" with value "YES" to your arguments on your executeable:
Right click your executeable, select get info and add that entry to the variables in the bottom list.
This will tell you what datatype has crashed.
Using build & analyze it tells me that you are releasing inreg, input and keys twice.
All three variables will be autoreleased, your manual release will cause the later autorelease to fail and give you your BAD_ACCESS.
Don't manually release them, remove these three lines from your code:
[inreg release];
[input release];
[keys release];