iphone : proplem with table view - iphone

I have a problem with table view in iphone .. i can't figure out why it crashes everytime
will here is the code
- (void)viewDidLoad
{
[self checkAndCreatePList];
NSMutableDictionary* plistDict = [[NSMutableDictionary alloc] initWithContentsOfFile:pListPath];
self.animals = [plistDict objectForKey:#"Animals"];
[super viewDidLoad];
}
-(UITableViewCell *) tableView:(UITableView *) tableView cellForRowAtIndexPath:(NSIndexPath *) indexPath
{
static NSString *SimpleTableIdentifier =#"SimpleTableIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:SimpleTableIdentifier];
if(cell== nil){
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:SimpleTableIdentifier]autorelease];
}
NSUInteger row = [indexPath row];
cell.textLabel.text = [animals objectAtIndex:row];
return cell;
}
it's crashes at the line
cell.textLabel.text = [animals objectAtIndex:row];
and tells me that
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFDictionary objectAtIndex:]: unrecognized selector sent to instance

The Animals key in your plist refers to a dictionary, not an array. Dictionaries don't have a guaranteed order, so asking for an object at a particular index doesn't make sense.
In addition to this, you have a memory leak - plistDict is allocated but never released. Have you run the static analyser over your code?

[plistDict objectForKey:#"Animals"];
is returning a Dictionary not an Array like you are expecting. You need to check out your plist file to see if the data is correct.

the error seems that you are calling objectAtIndex on a NSDictionary object at line cell.textLabel.text = [animals objectAtIndex:row]; check what does animal contains at run time. For this use NSLog before this line. NSLog(#"%#",animals);

Looks like animals is some dictionary and you are calling objectAtIndex: method on it. objectAtIndex: is NSArray method.

Related

Sorting a tableview alphabetically with objects and showing alphabetic tableview headers, as Contact Book

I am working on a contact list for my iphone applications. I have made a custom object class that contains the following attributes.
Firstname
Lastname
Id
Now I want to make a contact list like the iphone's contact list. So with A-B-C-D-E-... as the tableview section headers. I was following this tutorial.
But he is just working with strings. My problem is lying inside the CellForRow. Here you can see what I have ATM.
NSString *alphabet = [firstIndex objectAtIndex:[indexPath section]];
//---get all states beginning with the letter---
NSPredicate *predicate =
[NSPredicate predicateWithFormat:#"SELF beginswith[c] %#", alphabet];
NSLog(#"list content is here %#",[listContent valueForKey:#"name"]);
NSArray *contacts = [[listContent valueForKey:#"name"] filteredArrayUsingPredicate:predicate];
NSLog(#"Contacts array is %#",contacts);
Contact *contact = nil;
contact = [contacts objectAtIndex:[indexPath row]];
NSLog(#"contact is in de else %#",contact.name);
NSString *text = [NSString stringWithFormat:#"%# %#",contact.name,contact.firstName];
cell.textLabel.text = text;
[cell setAccessoryType:UITableViewCellAccessoryDisclosureIndicator];
I crashes on the first row with the following Log
2013-02-07 10:52:47.963 Offitel2[7807:907] list content is here (
Claes,
Geelen,
Verheyen
)
2013-02-07 10:52:47.964 Offitel2[7807:907] Contacts array is (
Claes
)
2013-02-07 10:52:47.964 Offitel2[7807:907] -[__NSCFString name]: unrecognized selector sent to instance 0x208e2c20
2013-02-07 10:52:47.965 Offitel2[7807:907] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFString name]: unrecognized selector sent to instance 0x208e2c20'
Can anybody help me with this?
Kind regards
Follow these steps:
make an index alphabet array with all starting alphabet of words you are going to populate
Now sort it:
//sorting for english language
indexAlphabetArray = (NSMutableArray *)[indexAlphabetArray sortedArrayUsingSelector:#selector(localizedCaseInsensitiveCompare:)];
Now implement
-(NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView
{
return indexAlphabetArray;
}
Final suggestion, take a dictionary of all names and group name with firstletter as key in dictionary, Eg.:
nameDictionary:{
A:(
Astart,
Astop,
)
b:(
bstart,
bstop,
)
}
In this way indexAlphabetArray = [nameDictionary allKeys];
Edit: Lets make it more easy for you:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [[nameDictionary valueForKey:[indexAlphabetArray objectAtIndex:section]] count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *kCellID = #"cellID";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellID];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:kCellID];
}
NSArray *nameArray = [nameDictionary valueForKey:[indexAlphabetArray objectAtIndex:indexPath.section]];
cell.textLabel.text = [nameArray objectAtIndex:indexPath.row];
return cell;
}

Code working with xib, but not with Storyboard

I am newbie for iPhone application. I am learning how to get the JSON data and parse it and show it in table in iPhone. For that I am going through this video.
I made this with xib file and its working perfectly.
What I was trying is do this with Storyboard. I did same thing as I did for Stoaryboard, however the execution is getting break at below line.
cell.textLabel.text = [[news objectAtIndex:indexPath.row] objectForKey:#"title"];
Code I have is
-(UITableViewCell *) tableView:(UITableView *) tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(#"i m here 1");
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"MainCell"];
NSLog(#"i m here 2");
if (cell==nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"MainCell"];
NSLog(#"i m here 3");
}
NSLog(#"i m here 4");
cell.textLabel.text = [[news objectAtIndex:indexPath.row] objectForKey:#"title"];
// cell.textLabel.text = #"dadsf ad";
NSLog(#"i m here 5");
return cell;
}
In NSLog, I get output till i m here 4.
When I comment cell.textLabel.text = [[news objectAtIndex and uncomment cell.textLabel.text = #"dadsf ad";, it works and I see dadsf ad in iPhone.
// cell.textLabel.text = [[news objectAtIndex:indexPath.row] objectForKey:#"title"];
cell.textLabel.text = #"dadsf ad";
When I run with cell.textLabel.text = [[news objectAt, I get below screen.
Note:
I also went to simulator and did Reset Content and Setting, still facing same problem. Any idea why?
Update 1
I activate the NSZombieEnabled and run the code. I get in NSLOG as
JSONNewsStoryBoard[19389:11303] i m here 4
2013-01-06 11:26:15.327 JSONNewsStoryBoard[19389:11303] *** -[CFArray objectAtIndex:]: message sent to deallocated instance 0x7497040
Below is the screen shot.
Update 2 - ANSWER
I tried adding NSLog(#"checking news count %d", [news count]); in cellForRowAtIndexPath and I got same problem. Means news was null.
So I added
news = [NSJSONSerialization JSONObjectWithData:data options:nil error:nil];
in cellForRowAtIndexPath and it worked. :) :)
It appears that the news object has been deallocated sometime before objectAtIndex: is called on it, and this probably has something to do with the way interface builder and storyboard take over control of the objects you give them. Try checking if news is equal to nil at various points in your code. You may have to instantiate news at a different point in time.

NSMutableArray not updating and UITableView not reloading

I'm creating a chat application. I have 2 methods in my view controller one for sending and one for receiving the messages. In the sending method i create a NSMutableDictionary with two objects ..
NSMutableDictionary *msgFilter = [[NSMutableDictionary alloc] init];
[msgFilter setObject:messageStr forKey:#"msg"];
[msgFilter setObject:#"you" forKey:#"sender"];
[messages addObject:msgFilter];
"messages" is my main NSMutableArray for holding all the messages, whose property is set and synthesized and allocated. When i send the message it is properly added into the NSMutableArray and the UITableView is updated showing me the values in the cell.
I have a method in my appDelegate to check for messages received and use the same procedure to parse the data and store it in an NSMutableDictionary. This dictionary is then passed to the viewcontroller and added into the same NSMutableArray(messages) and i then call [self.chattable reloadData]. But this doesn't do anything. When i nsloged the NSMutableArray it only had the received message not the whole data(send + received).
Why is it not adding the received messages into the same array and why is it not refreshing my table. I've been trying to get it to work for days now...Plz help..
//Recives message section
NSMutableDictionary *msgFilter = [myDelegate msgFilter];
[messages addObject:msgFilter];
[self.tView reloadData];
//Tableview section
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [messages count];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath: (NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
NSDictionary *s = (NSDictionary *) [messages objectAtIndex:indexPath.row];
NSString *sender = [s objectForKey:#"sender"];
NSString *message = [s objectForKey:#"msg"];
if ([sender isEqualToString:#"you"])
{
cell.detailTextLabel.text = [NSString stringWithFormat:#"TX: %at", message];
}
else
{
cell.detailTextLabel.text = [NSString stringWithFormat:#"RX: %at", message];
}
return cell;
}
Declare messages array in Application Delegate. so it will be shared array. so might be your problem get solved. because it is shared array. so you can add Dictionary in messages array from any where, no need to pass dictionary between diff UIView.

Table View Crashing When Accessing Array of Dicitonarys

All,
When my table view loads, it accesses several delegate methods. When I configure the cell, I have it calling this method (where "linkedList" is an array of dictionarys):
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
// Configure the cell...
VUWIManager *vuwiManager = [VUWIManager sharedVuwiManager];
NSLog(#"%#", [[vuwiManager linkedList]objectAtIndex:indexPath.row]);
NSLog(#"TESTZOMGOFDSOJFDSJFPODJSAPFDS");
cell.textLabel.text = [[vuwiManager linkedList]objectAtIndex:indexPath.row];
return cell;
}
It crashes at the line cell.textLabel.text = [[vuwiManager linkedList]objectAtIndex:indexPath.row]; - I know I'm doing something wrong here but I'm not sure what it is. Again, linkedList is a NSMutableArray of NSDictionarys.
Edit: if I call cell.textLabel.text = [[vuwiManager linkedList]objectAtIndex:indexPath.row]; it returns:
{
IP = "192.168.17.1";
desc = "description";
}
in the debugger. Just thought I'd give a little bit of formatting details.
Thanks
You are trying to assign an object NSDictionary to cell.textLabel.text, which must be passed a NSString.
Did you want :
NSString *s = [NSString stringWithFormat:#"%#",
[[vuwiManager linkedList]objectAtIndex:indexPath.row]];
cell.textLabel.text = s;
?
Setting an NSString * to an NSDictionary * will likely result in a crash when it tries to access any string methods that are not implemented in the dictionary. If you want that string you are logging add a call to description.
cell.textLabel.text = [[[vuwiManager linkedList]objectAtIndex:indexPath.row] description];
It looks like you are setting cell.textLabel.text to a NSDictionary instead of an NSString. If linkedList is an NSMutableArray of NSDictionaries, then you need to add on objectForKey:#"String key" to access the string
cell.textLabel.text = [[[vuwiManager linkedList]objectAtIndex:indexPath.row] objectForKey:#"STRING_KEY_HERE"];

-[NSCFString objectAtIndex:]: unrecognized selector

I have this little problem I couldn't find in Google:
UITableView works fine until I start scrolling.
Error Message: `-[NSCFString objectAtIndex:]: unrecognized selector sent to instance 0x5f24870 `
Method:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *MyIdentifier = #"MyIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:MyIdentifier] autorelease];
}
// Set up the cell
int storyIndex = [indexPath indexAtPosition: [indexPath length]-1];
//populate cell
cell.textLabel.text = [[myArray objectAtIndex: storyIndex] objectForKey: #"subject"];
return cell;
}
Just guessed that was the "problem"-method... if you need more infos: please tell me :)
thanks for all your help!
EDIT:
myArray is just the normal NSArray *myArray
It's a sorted Array ->
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"lesson" ascending:YES];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
myArray = [resultArray sortedArrayUsingDescriptors:sortDescriptors];
resultArray (NSMutableArray) is the Result of an XML-Parser.. hope you can see my problem..
It means that you're sending an objectAtIndex: messages to an object of type NSString (or possibly CFString). Of course you're expecting myArray to be an array and not a string.
What probably happened is that your array is being released (almost certainly autoreleased) too early and that by the time the method above is called the memory that was being pointed at by myArray now holds a string.
In response to your edit...
This line:
myArray = [resultArray sortedArrayUsingDescriptors:sortDescriptors];
...is incorrect. The value is autoreleased. You need to retain it:
myArray = [[resultArray sortedArrayUsingDescriptors:sortDescriptors] retain];
Remember to release it before you close the view!
myArray is proberbly autoreleased. Use self.myArray to set the sorted array. (with the correct #property (retain) )
If you have correctly identified this method as the culprit I'm guessing this line is the problem:
cell.textLabel.text = [[myArray objectAtIndex: storyIndex] objectForKey: #"subject"];
To me it looks lime myArray is an instance of NSCFString and not a NSArray. You should start by double checking that and that you never assign anything but NSArray instances to myArray.
--edit--
Try
self.myArray = [resultArray sortedArrayUsingDescriptors:sortDescriptors];
That should correctly retain the array for yoy to make sure it is not garbage collected and replaced with a rouge string :)
If myArray is an instance variable instead of a property, try:
myArray = [[resultArray sortedArrayUsingDescriptors:sortDescriptors] retain];