Leak when I load custom UITableViewCells from Xib files? - iphone

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!

Related

Determine different cells for iPhone and iPad in tableView:cellForRowAtIndexPath:

I just try to create an app for iPhone and iPad. For this i created a tableview that creates cells expecting the json that will be received when the app is loading. Inside the method
tableView:cellForRowAtIndexPath:
I initiate the cell that will be used for the iPhone and I set the specific values from the json. The cell I use is a custom Cell i created with a new object and NIB-File. The code looks like this:
static NSString *CellIdentifier = #"tvChannelIdentifier";
tvChannelCell *cell = (tvChannelCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"tvChannelCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
....
Now that I try to make the app work on the iPad too, I created a new custom cell, also with a new object and a NIB-File. The names of the variables are the same as in the customIPhoneCell so that I don't have to change the whole code. I just inserted a switch inside the tableView:cellForRowAtIndexPath: so that i show the right cell but it can't be accessed by the code:
static NSString *CellIdentifier = #"tvChannelCell";
static NSString *IPadCellIdentifier = #"tvChannelIPadCell";
//determination which device ---> choose cell
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone){
tvChannelCell *cell = (tvChannelCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
}else{
tvChannelIPadCell = (tvChannelIPadCell *) [tableView dequeueReusableCellWithIdentifier:IPadCellIdentifier];
}
I tried to define the cell objects at the top of the class but then i can't use the same variable name. I also tried to choose the NIB file of the iPad to check if it'll be displayed but nothing happens. And I tried to set an UITableviewcell at the top,
UITableViewCell *cell
and set the specific cell type inside my switch in cellForRowAtIndexPath but then the variables can't be accessed.
So my question is, is it possible to do this switch inside the tableview method or do i have to code to several parts for each device where each celltype has its own variablename?
What I do:
I create only one UITableViewCell subclass with 2 xibs, one xib for iPad and another for iPhone.
tvChannelCell *cell = (tvChannelCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
NSArray *nib;
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone){
nib = [[NSBundle mainBundle] loadNibNamed:#"tvChannelCell_iPhone" owner:self options:nil];
}else{
nib = [[NSBundle mainBundle] loadNibNamed:#"tvChannelCell_iPad" owner:self options:nil];
}
cell = [nib objectAtIndex:0];
}
this line of code useful for differenciating iphone and ipad,
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
tvChannelCell *cell = (tvChannelCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
}else{
cell = (tvChannelIPadCell *) [tableView dequeueReusableCellWithIdentifier:IPadCellIdentifier];
}
It's quite simple, why don't you create another nib for iPad, and just access it when device is iPad.
You all code will remain same, i.e. you don't need to compare iPad like anywhere
Like:
if (cell == nil) {
NSArray *nib;
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone){
nib = [[NSBundle mainBundle] loadNibNamed:#"tvChannelCell-iPad" owner:self options:nil];}
else{
nib = [[NSBundle mainBundle] loadNibNamed:#"tvChannelCell" owner:self options:nil];}
cell = [nib objectAtIndex:0];
}

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

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;
}
}

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/

UITableView is loading the same cells of some reason

I have a TableView loading a custom cell and loading the data from a JSON string on a server.
The JSON string is parsed to an array of 14 IDs (id_array).
If cell==nil, then I'm using [id_array objectAtIndex:indexPath.row] to get an ID and fetch some more info about for that row from a server, and set up the cell's labels and image.
When running the app, the UITableView is loading the visible rows [0,1,2,3,4] (cell height is 70px).
When scrolling down the TableView, row [5] is loaded and fetching data from the server, but the problem is that beyond that point - the TableView is repeating those 6 rows instead of requesting new data from the server for the new rows...
But it does request new data for row [5], which is not visible (and not loaded) when the app first runs.
Anyone have any idea why is this happening?
Thanks!
EDIT: Here is my cellForRowAtIndexPath method
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"CustomCell";
CustomCell *cell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"CustomCell" owner:self options:nil];
for (id currentObject in topLevelObjects) {
if ([currentObject isKindOfClass:[UITableViewCell class]]) {
cell = (CustomCell *)currentObject;
NSString *appsURL = [NSString stringWithFormat:#"http://myAPI.com?id=%#",[app_ids objectAtIndex:indexPath.row]];
NSLog(#"row -> %d | id -> %#",indexPath.row,[app_ids objectAtIndex:indexPath.row]);
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:appsURL]];
[cell updateAppInfoForCellWithRequest:request];
break;
}
}
}
// Configure the cell...
return cell;
}
If you are setting data only if cell==nil, then that is your issue. UITable builds a cache of table view cells, only creating a new one if cell is nil. Therefore, you must set your data each time, i.e. outside of the cell==nil block.
The example below shows that process. First, grab a cell from the pool, if there isn't a free cell, create a new one. Set the cell's values for the appropriate row.
- (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];
}
id someData = [id_array objectAtIndex:indexPath.row]
cell.textLabel.text = [someData someString];
return cell;
}

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.