# Amanda's Relationship Tips app, with scroll performance issues

I am having some major issues with scrolling in my active app "Amanda's Relationship Tips"

I'm using the Parse Database as a backend to pull user data. This lag is presenting a huge problem with Overall User Experience and I want to solve it, but I'm coming up short. I think (90% sure) that it's totally related with pulling the user images from parse. Here is the following code that is in the app currently:

//-------------------------------------------------------------------------------------------------------
- (PFTableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath object: (PFObject *)object
//-------------------------------------------------------------------------------------------------------
{
static NSString *myWallTableIdentifier = @"UserPostsCell";
WallCell *cell = [tableView dequeueReusableCellWithIdentifier:myWallTableIdentifier];
if (cell == nil)
{
cell = [[WallCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:myWallTableIdentifier];
}

//////////////////////////CONFIGURE THE CELL//////////////////////////

PFUser * user = object[@"User"];
[user fetchIfNeeded];

////USER NAME//////////////////////////////////////
UILabel *cUser = (UILabel*) [cell viewWithTag:105];
cUser.text = [object objectForKey:@"Post_Author"];

if (cUser.text == nil) {
cUser.text = [NSString stringWithFormat:@"Anonymous User"];
}

//User's Profile Picture//
profilePictureAttributes *thumbnailImageView = (profilePictureAttributes*)[cell viewWithTag:106];
{
if (error == nil)
{
thumbnailImageView.image = [[UIImage alloc] initWithContentsOfFile:path];
NSLog(@"No Error with PictureURL");
}
else
{
thumbnailImageView.file = user[PF_USER_PICTURE];
NSLog(@"Error with PictureURL trying to pull Parse File");
}
}];

////DATE LABEL (WHEN CREATED)/////////////////////////
UILabel *dateLabel = (UILabel*) [cell viewWithTag:102];
NSDate *parseDate = object.createdAt;
NSString *timeAgoFormattedDate = [parseDate formattedAsTimeAgo];
[dateLabel setText:[NSString stringWithFormat:@"%@", timeAgoFormattedDate]];
NSLog(@"%@", timeAgoFormattedDate);

////DESCRIPTION TEXT OF POST/////////////////////////////////
UITextView *postLabel = (UITextView*) [cell viewWithTag:103];
postLabel.text = [object objectForKey:@"body"];

////COMMENT BUTTON/////////////////////////////////////////////////////
CommentButton *commentButton = (CommentButton*) [cell viewWithTag:222];
commentButton.index = indexPath.row;

////////////////////////////
[cell configureCell:object];
return cell;
}


I have been told before that using tags for my cell's is a terrible idea, and to be honest, that's the only way I know of how to reference the make-up of my cell.

I get the warning in the console that a long-running operation is being executed on the main thread. When I check instruments, the lag is 2999MS on the main thread. I would greatly appreciate any help!

• I have pinpointed the problem down to this line of code: PFUser * user = object[@"User"]; [user fetchIfNeeded]; – Joshua Hart Jan 20 '16 at 19:05
• I suggest that you either write a self-answer if you are satisfied, or just edit the question with the revised code if you still are still interested in having your code reviewed. – 200_success Jan 21 '16 at 7:09

What is this?

//////////////////////////CONFIGURE THE CELL//////////////////////////

////USER NAME//////////////////////////////////////

//User's Profile Picture//

////DATE LABEL (WHEN CREATED)/////////////////////////

////DESCRIPTION TEXT OF POST/////////////////////////////////

////COMMENT BUTTON/////////////////////////////////////////////////////

////////////////////////////


It's good to break your code into small, digestable chunks, but when you're using comments like this to segment them out, you're doing it wrong.

If you'd just create some small, reusable, testable methods, you wouldn't need comments like this. The method names themselves will document every thing that's happening here.

 UILabel *cUser = (UILabel*) [cell viewWithTag:105];

profilePictureAttributes *thumbnailImageView = (profilePictureAttributes*)[cell viewWithTag:106];

UILabel *dateLabel = (UILabel*) [cell viewWithTag:102];

UITextView *postLabel = (UITextView*) [cell viewWithTag:103];

CommentButton *commentButton = (CommentButton*) [cell viewWithTag:222];


This sort of code is extraordinarily prone to error. We've taken the time to create our WallCell class, so why add the proper methods for setting our cell up correctly?

Seems like your WallCell class should have exposed the following methods:

- (void)setPostAuthor:(NSString *)author;
- (void)setProfilePicture:(UIImage *)profilePicture;
- (void)setPostDate:(NSDate *)date;
- (void)setPostMessage:(NSString *)message;


Although... I might argue that it should be even simpler. You should replace the first four methods with:

- (void)setPost:(WallPost *)post;


Where the WallPost class looks something like this:

@property User *postAuthor;
@property NSDate *postDate;
@property NSString *message;


And the User class looks something like this:

@property NSString *name;
@property UIImage *profilePicture;


(although, arguably, that last one is maybe just the URL to the picture)

Fetching the user info within cellForRowAtIndex was my problem. If you have a query outside cellForRowAtIndex just use includeKey in your query so that you only have to load all the information once.

For more performance in large lists you need use NSFetchedResultsController. This method itens in list only loaded data if the cell is showing in screen. But if you use this, identify if in columns filteted on query exists indexed.

When have many row The performance is affected.