I have a table view which gets data from a core data array. When I try to assign the value of the object "Post" to something or NSLog it the table scrolling lags.
Here is my code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"CellCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
Post *post = [array objectAtIndex:indexPath.row];
// If I comment out the NSLog the scroll is smoothly
NSLog(#"%#", post.title);
// Same thing for the line below
cell.textLabel.text = post.title;
return cell;
}
EDIT:
I'm using StackMob v1.2.0
Using NSLog will surely cause performance issues, especially in methods like cellForRowAtIndexPath which is invoked frequently.
Please check these article for details :
Dropping NSLog in release builds
The Evolution of a Replacement for NSLog
EDIT :
Also your implementation causes the slowness.
You are missing the allocation of tableviewCells.
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
First of all you should add the code that "Midhun MP" proposed.
If this doesnt help with the lagging problem...then i suppose post.title must be too heavy to be in that method (because that method gets called too many times)(Please let it not be that post.title uses internet connection to get the string?! Is it?)
Solution:
1)First thing in your app : Create an array2 and put in there all the post.title that u need(every time posts change you shoud update that array2)
2)use this array2 to get the text for the cells : cell.textLabel.textPost=[array2 objectAtIndex:indexPath.row];
3)I cant be 100% sure if NSLog is a problem because i havent tested that(could be..but this should only occur during debug...in release mode you shouldnt have it in there) but its easy to test and see(just comment the NSLog line)
Hope that helps.
Related
Searched and searched.. can't find an answer :|
I'm pretty sure I'm using insertRowsAtIndexPaths right... Here's my code, along with the error I'm receiving...
First, I receive a response back from the server with comments that I want to insert dynamically into an empty section within my static uitableviewcontroller's tableview.
This is what happens when we receive the response from the server...
I count the number of comments returned, and generate an array of index paths for the empty section, which is section 1.
I then run the standard way of inserting rows with encapsulation between begin/end updates.
Great..
Now, here's my tableview's related code.
Everything runs fine once I get the response from the server, insert I assume works...
However, when I start scrolling down the view, as soon as I scroll right before where the first comment would show, I get a crash with the following error, and nothing pointing me in any direction as to what it could be
It's the strangest thing... and from my NSLog right before the crash I can see it's attempting to get cell for index path of section 1 row 0, which would be where the first comment SHOULD be... What's going on??
UPDATE
Here is the value of self.recentComments prior to the indexPaths array being created.
UPDATE 2
Here's the value of self.recentComments in the cellForRowAtIndexPath RIGHT before the crash.
This is actually very strange. What i would suggest is you just do [self.tableView reloadData] instead to insertRowsAtIndexPath.
You do this once you get the response from the server :
-(void)loadRecentCommentsResponse:(NSDictionary *)data
{
int status = [[[data objectForKey:#"meta"] onjectForKey:#"status"] intValue];
if(status == STATUS_OK){
self.recentComments = [[data objectForKey:#"response"] objectForKeys:#"comments"];
[self.tableView reloadData];
}
}
SInce you are not reloading the UITableView it is unable to recognize the number of row to be displayed in the numberOfRowsInSection method.
Update :
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *cellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
//Do your stuff here
return cell;
}
You missed the if(!cell) block. It is used so that if the cell is not initialized, it is initialized. Whenever you scroll the UITableView this `cellForRowAtIndexPath method is called everytime.
Thanks.
EXC_BAD_ACCESS(code=1, address=0x71474b80)
This error appears when the user returns from scrolling all the way down in a nested UITableView. If I don't scroll to the bottom, the error doesn't happen.
maybe there is a deallocation problem as suggested by
UIViewTableController: "EXC_BAD_ACCESS" When Scrolling Up/Down Past the Max Position of the Table
My code is:
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *CellIdentifier = #"TroncalesInfo";
TroncalesViewCell *cell = [[TroncalesViewCell alloc]init];
cell = [tabla dequeueReusableCellWithIdentifier:CellIdentifier];
cell.IDTroncal = [nombresTroncales objectAtIndex:indexPath.row];
[cell setCellAtributes:indexPath db:dataBase];
return cell;
}
This is a little hack I always use. I don't know exactly why it works, but give it a try ;).
Insert this in the viewWillDisappear of your viewController:
tabla.delegate = nil;
I don't know if this is the source of your problem, but this code:
TroncalesViewCell *cell = [[TroncalesViewCell alloc]init];
cell = [tabla dequeueReusableCellWithIdentifier:CellIdentifier];
should be closer to this:
TroncalesViewCell *cell = [tabla dequeueReusableCellWithIdentifier:CellIdentifier];
if (!cell) {
cell = [[TroncalesViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
I think your existing code might return a nil cell, which would throw an exception. Right now you are pointlessly initializing a cell and then throwing it away and replacing it with another one.
From the crash log, it seems that the delegate of TroncalesViewController has been realloced when it should not be. You can check to make sure TroncalesViewController's delegate is still alive when you scroll the view.
I am creating a simple app to select video urls out of a UITable. I have hooked my data source and delegate to a UIViewController subclass and the table is filled correctly. Also, it recognizes selections and prints to the log.
My issue is that it gets a "EXC_BAD_ACCESS" and crashes when I select a cell. I am looking through the code and the error propagates to this method:
-(UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString* cellIdentifier = #"SelectionIdentifier";
//Errors start happening this next line
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if(cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier] autorelease];
}
//NSString* str = [[videos objectAtIndex:[indexPath row]] lastPathComponent];
NSString* test = #"test";
[[cell textLabel] setText:test];
return cell;
}
-(void) tableView:(UITableView*)myTableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// NSLog(#"Selected!");
}
-(NSInteger)tableView:(UITableView*)tableView numberOfRowsInSection:(NSInteger)section {
return [videos count];
}
I'm not sure why this error is getting thrown in this method. Any fixes? I double checked to make sure the videos array wasn't nill.
I did another app that used this same method and it doesn't cause these errors.
Any help or suggestions would be greatly appreciated!
Instead of testing if(cell == nil) try using if(!cell). Honestly I'm not sure this is the issue, but after reviewing this I do not think that the error is not actually inside this method (it may somehow be related which is why it brings you here).
If this is only after you select a cell though, why is this method being called?
I think you should also call this method.Because this is preliminary delegate method
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
After seeing your tableView i am not finding any problem at all.Try that may be it will be solve.
I'm using the table view in the view controller, with the simple array was displayed in the list. That array was displays and works fine but I'm getting this warning. May I know the reason for this and please some ideas to rectify this issues..
WARNING: Using legacy cell layout due to delegate implementation of
tableView:accessoryTypeForRowWithIndexPath: in . Please remove your implementation of this method and set
the cell properties accessoryType and/or editingAccessoryType to move
to the new cell layout behavior. This method will no longer be called
in a future release.
Thanks
The method tableView:accessoryTypeForRowWithIndexPath: is deprecated in iPhone OS 3.0. Delete the implementation of this method and add the following code in the method cellForRowAtIndexPath: :
cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;
See UITableViewCellAccessoryType in the documentation for other type.
Im using the following code as you mentioned :
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
}
// Set up the cell...
cell.text = [arry objectAtIndex:indexPath.row];
cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;
return cell;
}
But it returns the same
Its just saying that this method is about to disappear in next version, so you should go to documentations look for tableView:accessoryTypeForRowWithIndexPath and surely you will find alternative ways of doing what you want you want to do.
In other words, set the accessory of that cell by calling UITableViewCell accessory-view and accessory-type properties
myCell.accessoryType = ...
myCell.accessoryView = ...
My UITableView is returning EXEC_BAD_ACCESS, but why!
See this code snippet!
Loading the UITableView works fine, so allXYZArray != nil and is populated!
Then scrolling the tableview to the bottom and back up causes it to crash, as it goes to reload the method cellForRowAtIndexPath
It fails on line:
"NSLog(#"allXYZArray::count: %i", [allXYZArray count]);"
(UITableViewCell *)tableView:(UITableView *)theTableView cellForRowAt
IndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"CellIdentifier";
UITableViewCell *cell = [theTableView dequeueReusableCellWithIdentifier:CellIdentifier];
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
#try
{
if (allXYZArray == nil) {
NSLog(#"nil");
allXYZArray = [ToolBox getMergedSortedDictionaries:allXYZGiven SecondDictionary:allXYZSought];
}
NSLog(#"%i", [indexPath row]);
NSLog(#"allXYZArray::count: %i", [allXYZArray count]);
EXC_BAD_ACCESS means that your program is trying to access a memory address that is invalid or otherwise inaccessible from your process. This most commonly happens when you try send a message to an object that has already been dealloced. So the first step in debugging EXC_BAD_ACCESS is to figure out which object your program was trying to send a message to when the crash happened. Often the answer isn't obvious, in which case, NSZombieEnabled is a great tool for identifying which line of code caused the crash.
In your case you've already determined that the crash happens when you call [allXYZArray count], making allXYZArray our prime suspect. This object is being returned from +[ToolBox getMergedSortedDictionaries:SecondDictionary:], so it's likely that your bug is in the implementation of that method. I would guess that it's returning an object that has already been released instead of autoreleased, as prescribed by the Memory Management Programming Guide for Cocoa. (This is one of the most important documents in the SDK, by the way. I recommend rereading it once a month until its policies and techniques become second nature.)
Ok, reusing a cell, does not guarantee that the cell will be initialized properly:
UITableViewCell *cell = [theTableView dequeueReusableCellWithIdentifier:CellIdentifier];
cell will sometimes be null (especially the first time I guess).
Check cell for null and if so, initialize it properly.
if (cell == nil)
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];