Can't pass arguments to singleton function in xcode - iphone

I have a singleton in application and need to call its function with arguements from another class, but when I call it, nil arguements are passed...here is the code:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
NSLog([Singleton sharedMySingleton].test);
NSDictionary *story = [self.filters objectAtIndex: indexPath.row];
MainAppRecord *record = [[[MainAppRecord alloc]init]retain];
record.name = [story objectForKey:#"Name"];
record.searchUrl = [story objectForKey:#"SearchUrl"];
record.icon = [imageCash objectForKey:indexPath];
[[Singleton sharedMySingleton] changeMainFilterTo:record atPosition:indexOfFilterToChange];
}
Here is Singleton.h and its function:
#interface Singleton : NSObject {
NSMutableArray *mainFilters;
NSString *test;
}
#property (nonatomic, retain) NSMutableArray *mainFilters;
#property (nonatomic, retain) MainAppRecord *filterToChange;
-(void) initWithPlist;
-(void) saveToPlist;
-(void)changeMainFilterTo:(MainAppRecord*)record atPosition:(int)position;
+(Singleton *)sharedMySingleton;
#end
-(void)changeMainFilterTo:(MainAppRecord*)record atPosition:(int)position
{
[mainFilters insertObject:record atIndex:position];
}
The app crashes with
2012-10-20 16:24:52.789 TableView[1957:207] -[__NSArrayI insertObject:atIndex:]: unrecognized selector sent to instance 0x68410f0
Thanks

This is nothing to do with arguments not being passed, or singletons.
You've declared an NSMutableArray property in your singleton, but it looks like you've assigned an NSArray to it. You don't show where you set this up but it looks like you're loading it from a property list - this creates a immutable array by default. You then try to insert an object - which up can't do to an immutable array.
Ensure that when you create the array, you are creating a mutable array.
The simplest way to do this is to find the code where you are currently assigning the array, and make a mutable copy instead:
self.mainFilters = [[NSKeyedUnarchiver unarchiveObjectWithData:other] mutableCopy];

Related

NSMutableDictionary + NSMutableArray crash

I have an NSMutableDictionary called "myScheduleFullDictionary" set up like this:
KEY VALUE
"Day 1" An NSMutableArray of NSMutableDictionaries
"Day 2" An NSMutableArray of NSMutableDictionaries
"Day 3" An NSMutableArray of NSMutableDictionaries
etc.
I'm trying to parse it - basically grab one of the MutableArrays contained as the Value of one of the Keys.
Here is my code:
// First I make a mutableCopy of the entire Dictionary:
NSMutableDictionary *copyOfMyScheduleDictionary = [myScheduleFullDictionary mutableCopy];
// Next I grab & sort all the KEYS from it:
NSArray *dayKeysArray = [[copyOfMyScheduleDictionary allKeys] sortedArrayUsingSelector:#selector(compare:)];
// I set up an NSMutableArray to hold the MutableArray I want to grab:
NSMutableArray *sessionsInThatDayArray = [[NSMutableArray alloc] init];
// Then I iterate through the KEYs and compare each to the one I'm searching for:
for (int i = 0; i < [dayKeysArray count]; i++) {
NSString *currentDayKey = [dayKeysArray objectAtIndex:i];
if ([currentDayKey isEqualToString: targetDayString]) {
NSLog(#"FOUND MATCH!!!");
// I log out the NSMutableArray I found - which works perfectly:
NSLog(#"found array is: %#", [copyOfMyScheduleDictionary objectForKey:currentDayKey]);
// But when I try to actually grab it, everything crashes:
sessionsInThatDayArray = [copyOfMyScheduleDictionary objectForKey:currentDayKey];
break;
}
}
The error I get is:
-[__NSDictionaryM name]: unrecognized selector sent to instance 0x1c5fb2d0
Not sure why its pointing out "name" as the "unrecognized selector." "name" is an NSString property of a "Session" class I declared and am working with - could that be related somehow?
Any insights?
EDIT:
Here is my "SessionObject" class definition:
#interface SessionObject : NSObject
#property (nonatomic, strong) NSString *name;
#property (nonatomic, strong) NSString *speaker;
#property (nonatomic, strong) NSString *location;
#property (nonatomic, strong) NSDate *startTime, *endTime;
#property (nonatomic, strong) NSString *notes;
#property (nonatomic, strong) NSString *dayOfConference;
#end
-[__NSDictionaryM name]: unrecognized selector sent to instance 0x1c5fb2d0
This means that you are trying to call name on an NSMutableDictionary where as you should have called it on an object of class SessionObject. Check the line where you are calling something like myObject.name or [myObject name] and see if myObject is of type SessionObject and not NSMutableDictionary.
Here __NSDictionaryM denotes the NSMutableDictionary type.
I'm not sure where your bug comes from - but what are you doing there? Why don't you just write
sessionsInThatDayArray = [myScheduleFullDictionary objectForKey:targetDayString];
??? That's what NSDictionary is there for - you don't search for things by hand, you just call the method to look up the key. Instead you copied the dictionary, you extracted all the keys, you sorted the keys, you iterated through them one by one until you found it - and then you called objectForKey!!!
Apart from that, in the debugger set a breakpoint on all Objective-C exceptions. It will stop when the offending code is called, so no need to search for a needle in the haystack.

how to create Array of my NSObject class

I have created a new NSObject class as below:
#interface LoginObject : NSObject {
NSString *fName;
NSString *lName;
NSString *sessionId;
NSString *result;
NSString *response;
}
Now I can create an object of this type as:
LoginObject *login;
What do i need to do in order to create an NSMutableArray of my own NSObject class.
can any body guide?
Thanks
Just have a look at the NSMutableArray documentation here - http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSMutableArray_Class/Reference/Reference.html
Use one of the init or array methods.
arrayWithObjects is the one I use most often.
In Which class you want to have this array, you can create-
#property (nonatomic, retain) NSMutableArray *loginObjectArray;
in implementation file-
LoginObject *myLoginObject = [[LoginObject alloc] init];
myLoginObject.fName = ---
......
[loginObjectArray addObject:myLoginObject];
....
Don't forget to initialize loginObjectArray.
First create objects of your class,an array as -
LoginObject *obj1 = [[LoginObject alloc]init];
obj1.fName = #"xxxx";
-----------
LoginObject *obj1 = [[LoginObject alloc]init];
obj1.fName = #"xxxx";
-----------
// create a array with above objects
// nil indicate end of array
NSMutableArray *users = [[NSMutableArray alloc]initWithObjects:obj1,obj2,...,nil];
//if you want you can add other objects too -
[users addObject:obj10];

How to retain this object when inserting to mutable array?

update: I have found the bug in my copyWithZone method in A. Thanks everyone.
update: sorry, I do have the #properties declared, I thought it was obvious so I skipped them in my OP. Sorry about that.
The crash message is: objA was released (zombie) memory when trying to access the str.
My data structure looks like this:
#class A
{
NSString *str;
}
#property (retain) NSString *str; // str synthesized in .m
#class B
{
A *objA;
}
#property (copy) A *objA; // objA synthesized in .m
What I am trying to do is:
B *newB = [[B alloc] init];
[someMutableArray addObject: newB];
However, I will crash some times when I try to access like this:
B *myB = [someMutableArray objectAtIndex: index];
someLabel.text = myB.objA.str;
I guess the objA & objA.str were not retained when inserting B into the array. But I don't know how to make sure they are retrain.
Any help is appreciated
-Leo
You should be using properties for Class A and B:
#interface A : NSObject {
NSString *str;
}
#property (nonatomic, retain) NSString *str;
#end
The use #synthesize str; in .m file, this will retain the str, don't forget to release the str in the dealloc method:
#implementation A
#synthesize str;
- (void) dealloc {
[str release], str= nil;
[super dealloc];
}
#end;
You should look in to
http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjectiveC/Chapters/ocProperties.html%23//apple_ref/doc/uid/TP30001163-CH17
to learn about properties and how they manage memory.
Have you tried:
[someMutableArray addObject: [newB copy] ];
At this line
someLabel.text = myB.A.str;
it should be...
someLabel.text = myB.objA.str;
Yes, also you should be using properties for the members of your class. That will retain them. Just don't forget to release in dealloc

NSMutableArray crashes when adding after proper initialization

I have an NSMutableArray defined as a property, synthesized and I have assigned a newly created instance of an NSMutableArray. But after this my application always crashes whenever I try adding an object to the NSMutableArray.
Page.h
#interface Page : NSObject
{
NSString *name;
UIImage *image;
NSMutableArray *questions;
}
#property (nonatomic, copy) NSString *name;
#property (nonatomic, retain) UIImage *image;
#property (nonatomic, copy) NSMutableArray *questions;
#end
Page.m
#implementation Page
#synthesize name, image, questions;
#end
Relevant code
Page *testPage = [[Page alloc] init];
testPage.image = [UIImage imageNamed:#"Cooperatief leren Veenman-11.jpg"];
testPage.name = [NSString stringWithString:#"Cooperatief leren Veenman-11.jpg"];
testPage.questions = [[NSMutableArray alloc] init];
[testPage.questions addObject:[NSNumber numberWithFloat:arc4random()]];
The debugger reveals that the moment I use testPage.questions = [[NSMutableArray alloc] init]; the type of testPage.questions changes from NSMutableArray* to __NSArrayL* (or __NSArrayI*, not sure). I suspect this to be the problem, but I find it extremely odd. Anyone know what's happening here?
The problem is that you've declared the property as copy. This means your setter is going to be implemented something like this:
- (void) setQuestions:(NSMutableArray *)array {
if (array != questions) {
[questions release];
questions = [array copy];
}
}
The kicker here is that if you -copy an array (whether immutable or mutable), you will always get an immutable NSArray.
So to fix this, change the property to be retain instead of copy, and also fix this memory leak:
testPage.questions = [[NSMutableArray alloc] init];
It should be:
testPage.questions = [NSMutableArray array];
#property (nonatomic, copy) This setter declaration "copy" probably cast to NSArray why not retain or assign? I would retain anyway
You can also create a mutable copy method like so:
- (void)setQuestions:(NSMutableArray *)newArray
{
if (questions != newArray)
{
[questions release];
questions = [newArray mutableCopy];
}
}

How to add an object to NSMutableArray in Objective C?

NSMutableArray *tblContents = [NSMutableArray arrayWithObjects: #"1", #"2", #"3", nil];
[tblContents addObject:txtNewTableRow.text];
My app is crashing at line 2.
Error message in console is
'NSInvalidArgumentException', reason: '-[NSCFString addObject:]: unrecognized selector sent to instance xxx
BTW, it works alright if i replace arraywithobjects initialization with alloc & init!
I am simply creating a mutable array and adding an object to it. Whats the problem in there?
Thanks
Sridhar Reddy
Full code:
.h:
#import <UIKit/UIKit.h>
#interface TableStarterViewController : UIViewController
<UITableViewDelegate, UITableViewDataSource>
{
NSMutableArray *tblContents;
IBOutlet UITextField *txtNewTableRow;
IBOutlet UITableView *tblMain;
}
#property (nonatomic, retain) NSMutableArray *tblContents;
#property (nonatomic, retain) UITextField *txtNewTableRow;
#property (nonatomic, retain) UITableView *tblMain;
-(IBAction) addRowToTable;
#end
.m:
#import "TableStarterViewController.h"
#implementation TableStarterViewController
#synthesize tblContents;
#synthesize txtNewTableRow;
#synthesize tblMain;
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [tblContents count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:#"cell"];
cell.textLabel.text = [tblContents objectAtIndex:indexPath.row];
return cell;
}
-(IBAction) addRowToTable
{
[tblContents addObject:txtNewTableRow.text];
[tblMain reloadData];
}
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
tblContents = [NSMutableArray arrayWithObjects: #"1", #"2", #"3", nil];
[super viewDidLoad];
}
Thats all code.
Your are not retaining the array and it is being autoreleased before you are using it. Make sure to retain it after you get the pointer back from arrayWithObjects.
Also, it's not clear to me that arrayWithObjects will return a mutable array. Which, if not, will cause further problems.
Edit 1:
Alloc and Init return an object with retain count 1; arrayWithObjects returns an object with retain count 0.
Edit 2:
I pulled out Xcode and verified that [NSMutableArray arrayWithObjects:] return an NSMutableArray (or according to Xcode a __NSArrayM)
instead of,
tblContents = [NSMutableArray arrayWithObjects: #"1", #"2", #"3", nil];
try this,
tblContents = [NSMutableArray initWithObjects: #"1", #"2", #"3", nil];
As mentioned by aepryus, arrayWithObjects is inherited from NSArray and it might actually be returning NSArray. Hence the problem.
Anyone knows how to init NSMutableArray with objects?