-[__NSArrayM setTableViewStyle:]: error while creating a custom uitablevewcell - iphone

I've just created a custom cell in a tableview, I called the custom cell in UITableViewDelegate method
--(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
This is what my code looks like:
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *cellId = #"cellIdetifier";
static NSString *cellId2 = #"cellId2";
tableCell *customCell = [tableView dequeueReusableCellWithIdentifier:cellId2];
if(customCell == nil){
NSArray *customObjects = [[NSBundle mainBundle]loadNibNamed:#"tableCell" owner:self options:nil];
for(id obj in customObjects){
if([obj isKindOfClass:[tableCell class]]){
customCell = (tableCell *)customObjects;
break;
}
}
}
return customCell;
}
I'm getting a error which says
creatingcustomcell[693:f803] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSArrayM setTableViewStyle:]: unrecognized selector sent to instance 0x6d6c7f0'
Please help me, I have no clue what has just happened.

It's difficult to tell from this code if your coersion in line:
customCell = (tableCell *)customObjects;
is correct. At least it looks strange that you coerce an array:
NSArray *customObjects = [[NSBundle mainBundle]loadNibNamed:#"tableCell" owner:self options:nil];
to your tableCell
Do you mean:
customCell = (tableCell *)obj;
Also you might want to follow the recommendation that class names should be capitalized

if([obj isKindOfClass:[tableCell class]]){
customCell = (tableCell *)customObjects;
break;
}
You are setting the cell to the entire array
Do this instead
for (int i=0; i < customObjects.count; i++) {
if([customObjects objectAtIndex:i] isKindOfClass:[tableCell class]]){
customCell = (tableCell *)[customObjects objectAtIndex:i];
break;
}
}

Related

Populating UITableView with NSArray in iOS 7

A lot of the methods have deprecated in iOS 7 in order to set font, textLabel, and color for UITableView cells. I'm also just having a difficult time populating the view with these values. Here's a snippet of my code:
- (void)fetchedData:(NSData *)responseData {
//parse out the json data
NSError* error;
NSDictionary* json = [NSJSONSerialization
JSONObjectWithData:responseData
options:kNilOptions
error:&error];
NSArray* jobs = [json objectForKey:#"results"];
for(NSDictionary *jobsInfo in jobs) {
JobInfo *jobby = [[JobInfo alloc] init];
jobby.city = jobsInfo[#"city"];
jobby.company = jobsInfo[#"company"];
jobby.url = jobsInfo[#"url"];
jobby.title = jobsInfo[#"jobtitle"];
jobby.snippet = jobsInfo[#"snippet"];
jobby.state = jobsInfo[#"state"];
jobby.time = jobsInfo[#"date"];
jobsArray = [jobsInfo objectForKey:#"results"];
}
}
I am looping through an array of dictionaries from a GET request and parsed. I am now attempting to fill my UITableView with the following code:
-
(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return [jobsArray count];
}
- (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];
}
NSDictionary *jobsDic = [jobsArray objectAtIndex:indexPath.row];
[cell.textLabel setText:[jobsDic objectForKey:#"jobtitle"]];
return cell;
}
Also, I have declared this is in my .h file:
NSArray *jobsDic;
Any ideas on what I'm doing wrong? Is this an iOS 7 problem?
It seems that you reinitialize jobsarray at the end of the forin loop.
You didn't mean ?
NSArray* jobs = [json objectForKey:#"results"];
NSMutableArray *jobsTemp = [[NSMutableArray alloc] initWithCapacity:jobs.count];
for(NSDictionary *jobsInfo in jobs) {
JobInfo *jobby = [[JobInfo alloc] init];
jobby.city = jobsInfo[#"city"];
jobby.company = jobsInfo[#"company"];
jobby.url = jobsInfo[#"url"];
jobby.title = jobsInfo[#"jobtitle"];
jobby.snippet = jobsInfo[#"snippet"];
jobby.state = jobsInfo[#"state"];
jobby.time = jobsInfo[#"date"];
[jobsTemp addObject:jobby];
}
self.jobsArray = jobsTemp; //set #property (nonatomic, copy) NSArray *jobsArray; in the .h
[self.tableView reloadData]; //optional only if the data is loaded after the view
In the cell for row method :
- (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];
}
JobInfo *job = self.jobsArray[indexPath.row];
cell.textLabel.text = job.title;
return cell;
}
And don't forget :
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return self.jobsArray.count;
}
Update - an user suggested an edit :
It's true that count isn't a NSArray property. But as Objective-C lets us use a shortcut notation for calling method with a dot, this code works. You have to know limitation of this : if you use a NSArray subclass with a count property with a custom getter this could have side effects #property (nonatomic, strong, getter=myCustomCount) NSUInteger count. As I think code readability is to me one of most important things I prefer to use dot notation. I think Apple SHOULD implement count as readonly property so I use it this way (but it's my point of view). So for those which don't agree with me just read return [self.jobsArray count]; in the tableView:numberOfRowsInSection: method.
Change the declaration of jobsArray from NSArray to NSMutableArray.
Add an initialization at the beginning point of fetchedData method like follows.
if(!jobsArray) {
jobsArray = [NSMutableArray array];
}
else {
[jobsArray removeAllObjects];
}
Remove the following line.
jobsArray = [jobsInfo objectForKey:#"results"];
Instead of that, add the initialized object to the array at the end of for loop.
[jobsArray addObject:jobby];
Add a [tableView reloadData]; at the end of your *-(void)fetchedData:(NSData )responseData; method implementation.
Initially when you are loading the view, tableView will get populated. After you received the data, tableView will not be known that it is received.
Everything else seems good. Hope rest will work fine.

Uitableview displaying objects

I want to display the values of a NSMutableArray in a UITableView. In the NSMutableArray are values of objects. But the UITableView doesn't display anything. If I use a normal NSArray with static values it works well.
So this is my code:
This is my object
#interface Getraenke_Object : NSObject {
NSString *name;
}
my NSMutableArray
NSMutableArray *getraenkeArray;
here is where I get the values into the array:
for(int i = 0; i < [getraenkeArray count]; i++)
{
[_produktName addObject:[[getraenkeArray objectAtIndex:i]getName]];
NSLog(#"test: %#",_produktName);
}
and that is how I try to display it in the UITableView
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"ProduktCell";
ProduktTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[ProduktTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
int row = [indexPath row];
cell.produktName.text = _produktName [row];
return cell;
}
Just make your getraenkeArray as member and:
cell.produktName.text = [[getraenkeArray objectAtIndex:indexPath.row] getName];
it seems like you never allocated the NSMutableArray. you are missing:
_produktName = [NSMutableArray array];
and that's why the addObject is being sent to nil..

Leak when I load custom UITableViewCells from Xib files?

I am getting leak in following code. Leak percentage # the end of the line. Can anyone tell me what is the problem.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
coustomMessage *cell = (coustomMessage *)[tableView dequeueReusableCellWithIdentifier:#"coustomMessage"];
if (cell == nil) {
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"coustomMessage" owner:self options:nil]; (93.1%)
cell = [topLevelObjects objectAtIndex:0];
}
cell.nameLable.text = [self.nameArray objectAtIndex:indexPath.row]; (3.4%)
cell.messageStatusLable.text = [[self.endPointCountArray objectAtIndex:indexPath.row] stringValue]; (3.4%)
return cell;}
are you sure you setted the "identifier" property in your XIB file with the same name you use in your code (with: dequeueReusableCellWithIdentifier:#"coustomMessage")?
Superb! I had exactly the same issue I misspelled the identifier in the XIB and so lots of leaks as the cell we being recreated not re-used. Thanks!

How to print the array value in cells lable?

I am developing a application in that I want to print the array value in the cell contain label place. I got the vlaues for array like names=[results valueForKey:#"name"].
I write the code for print that value in a lable in cellForRowAtIndexPath like
-(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] autorelease];
}
NSInteger row=indexPath.row;
cell = [self getCellContentView:CellIdentifier];
UILabel *lblTemp1 = (UILabel *)[cell viewWithTag:1];
lblTemp1.text = [names objectAtIndex:row];
//lblTemp2.text = [names objectAtIndex:row];
return cell;
}
but ,when the application got the error at lblTemp1.text = [names objectAtIndex:row] like Program received signal: “EXC_BAD_ACCESS”.So please tell me how to solve this problem.
It seems you've missed to retain the array names. Try,
names = [[results valueForKey:#"name"] retain];
You could consider using declared properties to overcome the overhead of retaining and releasing the objects.
seems to be new bee. please check out for step by step tutorial
http://adeem.me/blog/2009/05/19/iphone-programming-tutorial-part-1-uitableview-using-nsarray/

iphone: UITABLEView crashing the application

dont know whats wrong with my table view, I have a dictionary(this dictionary is created by a sqlite operation) and I am trying to create cells like this
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *MyIdentifier = #"MyIdentifier";
MyIdentifier = #"tblCellView";
CustomCell *cell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if(cell == nil) {
[[NSBundle mainBundle] loadNibNamed:#"CustomCell" owner:self options:nil];
cell = aCustomCell;
aCustomCell=nil;
}
NSMutableDictionary *tempDictionary=[[NSMutableDictionary alloc] init];
tempDictionary=[offendersNamesList objectForKey:[NSString stringWithFormat:#"key%d", indexPath.row+1]];
[[cell offendersImageView] setImage:[UIImage imageNamed:#"contact.png"]];
[cell.offendersNameLbl setText:[tempDictionary objectForKey:#"name"]];
[cell.offendersViolation setText:[tempDictionary objectForKey:#"offence"]];
[tempDictionary release];
//[cell setLabelText:[arryData objectAtIndex:indexPath.row]];
return cell;
}
all the items are displayed correctly but when I scroll the table view up the application crashes can you help me in this?
You are first allocating a new NSMutableDictionary and store it in tempDictionary. However, in the very next line, you overwrite that variable with a pointer to a new object (tempDictionary=[offendersNamesList objectForKey:[NSString stringWithFormat:#"key%d", indexPath.row+1]];). So you've got a memory leak here, the [[NSMutableDictionary alloc] init] is unnecessary, remove it.
Now, due to the naming conventions, the object that you've got from the offendersNamesList is autoreleased, yet you later call [tempDictionary release]; and thus over-release it. Remove that as well.