My tableView freezes while reloading with rows more than 600. is there any solution for that.I am getting data in background thread and try to reload my table in main thread but still the issue is same.
this is my code in cellForRow..
if (![currentUID isEqualToString:[chatDict valueForKey:#"sender"]]) {
identifier = #"onlyRightChat";
}else{
identifier = #"onlyLeftChat";
}
UITableViewCell *cell ;
cell= [tableView dequeueReusableCellWithIdentifier:identifier ];
NSString *userName;
if ([chatDict valueForKey:#"sender_last_name"]) {
userName = [NSString stringWithFormat:#"%# %#",[chatDict valueForKey:#"sender_first_name"],[chatDict valueForKey:#"sender_last_name"]];
}else{
userName = [NSString stringWithFormat:#"%#",[chatDict valueForKey:#"sender_first_name"]];
}
NSString *str ;
if (![currentUID isEqualToString:[chatDict valueForKey:#"sender"]]) {
str = [NSString stringWithFormat:#"%#:\n%#",userName,[[Utils sharedObject] convertUnicodeToEmoji:[chatDict valueForKey:#"text"]]];
}else{
str = [NSString stringWithFormat:#"You:\n%#",[[Utils sharedObject] convertUnicodeToEmoji:[chatDict valueForKey:#"text"]]];
}
CGRect labelSize =[self getRectForString:str];
if (cell == nil) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:identifier];
}
cell.selectionStyle = UITableViewCellSelectionStyleNone;
TTTAttributedLabel *lbl = (TTTAttributedLabel *)[cell.contentView viewWithTag:5111];
UIView *lblBgView = (UIView *)[cell.contentView viewWithTag:5113];
UIView *bgView = (UIView *)[cell.contentView viewWithTag:5115];
UILabel *timeLbl = (UILabel *)[cell.contentView viewWithTag:5114];
UIImageView *userImgView = (UIImageView *)[cell.contentView viewWithTag:5116];
UILabel *onlineIcon = (UILabel *)[cell.contentView viewWithTag:onlineStatusTag];
onlineIcon.layer.cornerRadius = onlineIcon.frame.size.height/2.0;
onlineIcon.clipsToBounds = YES;
lbl.backgroundColor = [UIColor clearColor];
lbl.enabledTextCheckingTypes = NSTextCheckingTypeLink|NSTextCheckingTypePhoneNumber|NSTextCheckingTypeAddress;
lbl.delegate = self;
if (![currentUID isEqualToString:[chatDict valueForKey:#"sender"]]) {
lbl.linkAttributes = #{NSForegroundColorAttributeName:[UIColor colorWithRed:91/255.0f green:135/255.0f blue:198/255.0f alpha:1.0] ,NSUnderlineStyleAttributeName: #(NSUnderlineStyleSingle)};//[UIColor colorWithRed:119/255.0f green:195/255.0f blue:66/255.0f alpha:1.0]
}else{
lbl.linkAttributes = #{NSForegroundColorAttributeName:[UIColor colorWithRed:194/255.0f green:228/255.0f blue:255/255.0f alpha:1.0] ,NSUnderlineStyleAttributeName: #(NSUnderlineStyleSingle)};//[UIColor colorWithRed:119/255.0f green:195/255.0f blue:66/255.0f alpha:1.0]
}
if ([currentUID isEqualToString:[chatDict valueForKey:#"sender"]]) {
onlineIcon.hidden = YES;
}else{
onlineIcon.hidden = NO;
NSString *status = [chatDict valueForKey:#"status"];
if(status){
if([status isEqualToString:#"online"]){
onlineIcon.backgroundColor = [UIColor colorWithRed:81/255.0 green:217/255.0 blue:93/255.0 alpha:1.0];
}else if([status isEqualToString:#"offline"]){
onlineIcon.backgroundColor = [UIColor yellowColor];
}else{
onlineIcon.backgroundColor = [UIColor colorWithRed:214/255.0 green:103/255.0 blue:101/255.0 alpha:1.0];
}
}else{
onlineIcon.backgroundColor = [UIColor yellowColor];
}
}
userImgView.layer.cornerRadius = userImgView.frame.size.height/2;
userImgView.clipsToBounds = YES;
[userImgView sd_setImageWithURL:[NSURL URLWithString:[chatDict valueForKey:#"sender_picture"]]placeholderImage:[UIImage imageNamed:#"default_avatar"]];
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(userImageViewTap:)];
tapGesture.numberOfTapsRequired = 1;
userImgView.userInteractionEnabled = YES;
[userImgView addGestureRecognizer:tapGesture];
// NSLog(#"cell.frame.size.width %f",cell.frame.size.width);
float width = cell.frame.size.width;
float height = cell.frame.size.height;
if (![currentUID isEqualToString:[chatDict valueForKey:#"sender"]])
{
bgView.frame = CGRectMake(width- labelSize.size.width-31-20-35,0,labelSize.size.width+31+20,cell.frame.size.height);
lblBgView.frame = CGRectMake(0,10,bgView.frame.size.width-15,labelSize.size.height+10);
lbl.frame = CGRectMake(8, 0, lblBgView.frame.size.width-16, labelSize.size.height+10);
timeLbl.frame = CGRectMake(width-170,height-25, 120,fontSize);
timeLbl.textAlignment = NSTextAlignmentRight;
}else{
bgView.frame = CGRectMake(35,0,labelSize.size.width+31+20,cell.frame.size.height);
lblBgView.frame = CGRectMake(15,10,bgView.frame.size.width-15,labelSize.size.height+10);
lbl.frame = CGRectMake(8, 0, lblBgView.frame.size.width-16, labelSize.size.height+10);
timeLbl.frame = CGRectMake(55,height-25, 120,fontSize);
timeLbl.textAlignment = NSTextAlignmentLeft;
}
NSDate* dateComment = [[Utils sharedObject] StringToDate:[chatDict valueForKey:#"created_at"] withFormat:#"yyyy-MM-dd'T'HH:mm:ss.SSSZZZZ"];
timeLbl.text = [[Utils sharedObject] relativeTimestamp:dateComment];
timeLbl.font = [UIFont fontWithName:#"Lato-Regular" size:fontSize-3.0];
lblBgView.layer.cornerRadius = 8.0f;
lblBgView.clipsToBounds = YES;
lbl.layer.cornerRadius = 8.0f;
lbl.font = [UIFont fontWithName:#"Lato-Regular" size:fontSize];
lbl.numberOfLines = 0;
lbl.clipsToBounds = YES;
if (str!=(id)[NSNull null])
{
if (![currentUID isEqualToString:[chatDict valueForKey:#"sender"]]) {
lbl.text = str;
}else{
NSDictionary *attrDict = #{ NSFontAttributeName : [UIFont fontWithName:#"Lato-Regular" size:fontSize], NSForegroundColorAttributeName : [UIColor colorWithRed:146/255.0 green:183/255.0 blue:201/255.0 alpha:1.0]};
NSMutableAttributedString *attrString = [[NSMutableAttributedString alloc] initWithString:#"You:\n" attributes: attrDict];
NSDictionary *attrDict1 = #{ NSFontAttributeName : [UIFont fontWithName:#"Lato-Regular" size:fontSize]};
NSMutableAttributedString *attrString1 = [[NSMutableAttributedString alloc] initWithString:[[Utils sharedObject] convertUnicodeToEmoji:[chatDict valueForKey:#"text"]] attributes: attrDict1];
[attrString appendAttributedString:attrString1];
lbl.text = str;
lbl.textColor = [UIColor whiteColor];
}
}else{
lbl.text= #"";
}
return cell;
}
and reload call from method..
-(void)getChatTextFromLocalDB{
// [self showLoadingView];
NSString *databaseKey = [NSString stringWithFormat:#"%#-%#",[self.m_dictInfo valueForKey:#"rid"],[[NSUserDefaults standardUserDefaults] objectForKey:#"rid"]];
NSString *localDBPath=[NSHomeDirectory() stringByAppendingPathComponent:#"Documents/GroupChat.plist"];
NSMutableDictionary *root = [[[NSMutableDictionary alloc] initWithContentsOfFile:localDBPath] mutableCopy];
NSMutableArray *chatDictAry = [root objectForKey:databaseKey];
NSString *localDBPath1=[NSHomeDirectory() stringByAppendingPathComponent:#"Documents/GeoConnectChat.plist"];
NSMutableDictionary *root1 = [[[NSMutableDictionary alloc] initWithContentsOfFile:localDBPath1] mutableCopy];
NSMutableArray *temp = [root1 objectForKey:#"chatDeleted"];
NSSortDescriptor *sorter = [[NSSortDescriptor alloc] initWithKey:#"created_at" ascending:YES];
NSArray *sorters = [[NSArray alloc] initWithObjects:sorter, nil];
NSArray *sortedArray = [chatDictAry sortedArrayUsingDescriptors:sorters];
NSString *lastMsgRid;
[chatDictAry removeAllObjects];
[chatDictAry addObjectsFromArray:sortedArray];
if(chatDictAry.count||[temp containsObject:databaseKey ]){
[self.chatArray removeAllObjects];
for (NSDictionary *dict in chatDictAry) {
if(!([g_Delegate.grpBlockByMeList containsObject:[dict valueForKey:#"sender"]]||[g_Delegate.grpBlockMeList containsObject:[dict valueForKey:#"sender"]])){
[self.chatArray addObject:dict];
if([dict valueForKey:#"rid"])
lastMsgRid = [dict valueForKey:#"rid"] ;
[self.usersArray addObject:[dict valueForKey:#"sender"]];
}
}
[root writeToFile:localDBPath atomically:YES];
dispatch_async(dispatch_get_main_queue(), ^(void){
[self hideLoadingView];
});
if (self.chatArray.count) {
if(tablePositionTop){
CGSize beforeContentSize = self.chatTableView.contentSize;
[self.chatTableView reloadData];
CGSize afterContentSize = self.chatTableView.contentSize;
CGPoint afterContentOffset = self.chatTableView.contentOffset;
CGPoint newContentOffset = CGPointMake(afterContentOffset.x, afterContentOffset.y + afterContentSize.height - beforeContentSize.height);
self.chatTableView.contentOffset = newContentOffset;
}
else{
[self.chatTableView reloadData];
int64_t delayInSeconds = 0.2f;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
if(actualSelf){
[self.chatTableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:[self.chatArray count]-1 inSection:0] atScrollPosition:UITableViewScrollPositionBottom animated:YES];
}
});
}
[self getUsersOnlineStatus];
if (isFirstTime) {
isFirstTime = NO;
[self getRemainingListFromServerWithLastMsgId:lastMsgRid];
}else{
// [self hideLoadingView];
}
}else{
[self hideLoadingView];
}
}
else
{
if (isFirstTime) {
isFirstTime = NO;
[self showLoadingView];
[self getAllMessages];
}
}
}
I suggest you watch Session 211 of WWDC 2012, Building Concurrent User Interfaces and apply the concepts there. This features cells whose contents are independently queried and rendered.
The basic concept is as follows:
1. In tableView:cellForRowAtIndexPath, a cell is instantiated.
2. In the same method, an operation for retrieving the data to populate the cell is created and stored into a dictionary. A reference to the cell is passed to the operation. The operation has a completion handler that populates the cell and removes the operation from the dictionary.
3. Before the cell is returned from the method, the operation is added to an operation queue.
4. In tableView:didEndDisplayingCell:forRowAtIndexPath, operations for cells that have moved off-screen are cancelled and removed from the dictionary.
Related
This is the cellForRowAtIndexPath :
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
MessageDetailCell *cell;
#try {
if(indexPath != nil && indexPath.row < arrMessages.count)
{
cell = [tableView dequeueReusableCellWithIdentifier:#"MessageDetailCell"];
if (cell == nil) {
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"MessageDetailCell" owner:self options:nil];
cell = [topLevelObjects objectAtIndex:0];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
cell.accessoryType = UITableViewCellAccessoryNone;
if ([cell respondsToSelector:#selector(layoutMargins)]) {
cell.layoutMargins = UIEdgeInsetsZero;
cell.preservesSuperviewLayoutMargins = false;
}
}
else
{
NSArray *arr = [cell.contentView subviews];
for(int i=0; i<[arr count]; i++)
{
UIView *view = [arr objectAtIndex:i];
[view removeFromSuperview];
}
}
cell.tag = indexPath.row;
cell.selectionStyle = UITableViewCellSelectionStyleNone;
cell.accessoryType = UITableViewCellAccessoryNone;
MessageThread *thread = [arrMessages objectAtIndex:indexPath.row];
float xAxis = 10.0;
float yAxis = 10.0;
float imageDimention = 40;
float fontSize = 20;
NSLog(#"");
if(indexPath.row == 0)
{
xAxis = 10;
imageDimention = 40;
fontSize = 20;
cell.imgUserWidthConstraint.constant = 40;
cell.imgUserHeightConstraint.constant = 40;
cell.lblContentLeftConstraint.constant = 64;
cell.btnReplyLeftConstraint.constant = 64;
}
else
{
xAxis = 32 * thread.ReplyLevel;
imageDimention = 32;
fontSize = 17;
cell.imgUserWidthConstraint.constant = 32;
cell.imgUserHeightConstraint.constant = 32;
cell.lblContentLeftConstraint.constant = 110;
cell.btnReplyLeftConstraint.constant = 110;
}
if(![thread.sender.Image isEqual:#""] && ![thread.sender.Image.lowercaseString containsString:#"default"])
[self createImage:CGRectMake(xAxis, yAxis, imageDimention, imageDimention) cell:cell messageThread:thread];
else
{
UILabel *lblLetter = [[UILabel alloc]initWithFrame:CGRectMake(xAxis, yAxis, imageDimention, imageDimention)];
lblLetter.layer.cornerRadius = lblLetter.frame.size.width / 2;
lblLetter.layer.borderColor = [[UIColor blackColor] CGColor];
lblLetter.layer.borderWidth = 0.8;
lblLetter.layer.masksToBounds = YES;
lblLetter.backgroundColor = [UIColor colorWithRed:239.0/255.0 green:239.0/255.0 blue:239.0/255.0 alpha:1.0];
lblLetter.text = [thread.sender.FirstName substringToIndex:1];
lblLetter.font = [UIFont boldSystemFontOfSize:fontSize];
lblLetter.textAlignment = NSTextAlignmentCenter;
lblLetter.textColor = [UIColor blackColor];
[cell.contentView addSubview:lblLetter];
}
cell.imgUserLeftConstraint.constant = xAxis;
xAxis = 80;
NSString *recipients = #"";
for(Recipient *rp in thread.Recipients)
{
recipients = [recipients stringByAppendingString:[NSString stringWithFormat:#"%#, ", rp.Name]];
}
recipients = [recipients substringToIndex:recipients.length - 2];
NSAttributedString * attrUserText;
attrUserText = [[NSAttributedString alloc] initWithData:[[NSString stringWithFormat:#"%# → %#", thread.sender.FullName, recipients] dataUsingEncoding:NSUnicodeStringEncoding] options:#{ NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType } documentAttributes:nil error:nil];
NSAttributedString *attrArrow = [[NSAttributedString alloc] initWithData:[[NSString stringWithFormat:#" → %#", recipients] dataUsingEncoding:NSUnicodeStringEncoding] options:#{ NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType } documentAttributes:nil error:nil];
NSMutableAttributedString *string = [[NSMutableAttributedString alloc]initWithAttributedString:attrUserText];
int firstHalf = (int)thread.sender.FullName.length;
int secondHalf = (int)attrArrow.length;
[string addAttribute:NSForegroundColorAttributeName value:[UIColor lightGrayColor] range:NSMakeRange(firstHalf,secondHalf + 1)];
[string addAttribute:NSForegroundColorAttributeName value:[UIColor blackColor] range:NSMakeRange(0,firstHalf)];
cell.lblUsers.attributedText = string;
cell.lblUsers.textAlignment = NSTextAlignmentLeft;
cell.lblUsers.font = [UIFont boldSystemFontOfSize:15];
cell.lblUsers.numberOfLines = 0;
cell.lblDate.text = [self returnDate:thread.CreatedOn];
cell.lblDateTopConstraint.constant = 10;
cell.lblDate.textAlignment = NSTextAlignmentLeft;
cell.lblDate.font = [UIFont systemFontOfSize:12];
cell.lblContent.tag = (int)indexPath.row;
cell.lblContent.backgroundColor = [UIColor clearColor];
cell.lblContent.textColor = [UIColor blackColor];
cell.lblContent.textAlignment = NSTextAlignmentLeft;
cell.lblContent.font = [UIFont systemFontOfSize:14];
cell.lblContent.text = thread.MessageContent;
cell.lblContent.dataDetectorTypes = UIDataDetectorTypeLink;
cell.lblContent.dataDetectorTypes = UIDataDetectorTypeAll;
cell.lblContent.scrollEnabled = NO;
cell.lblContent.editable = NO;
cell.lblContent.selectable = YES;
cell.lblContent.contentInset = UIEdgeInsetsMake(0, -4, 0, 0);
[cell.lblContent layoutIfNeeded];
//
yAxis = yAxis + 30;
float yAxisDocAttachment = 0;
cell.viewAttachmentHeightConstraint.constant = 0;
BOOL isDoc = NO;
BOOL isImage = NO;
if(thread.attachments.count > 0)
{
for(MessageAttachment *msgDoc in thread.attachments)
{
if(![msgDoc.Type isEqual:#"Image"])
{
isDoc = YES;
cell.viewAttachmentCollection.hidden = NO;
cell.viewAttachmentTopConstraint.constant = 10;
if((int)indexPath.row != 0)
cell.viewAttachmentLeftConstraint.constant = xAxis - 16;
else
cell.viewAttachmentLeftConstraint.constant = xAxis;
UIView *viewAttachment = [[UIView alloc]initWithFrame:CGRectMake(0, yAxisDocAttachment, self.view.frame.size.width - cell.lblContent.frame.origin.x - 50, 80)];
viewAttachment.backgroundColor = [UIColor colorWithRed:234.0/255.0 green:234.0/255.0 blue:234.0/255.0 alpha:1.0];
viewAttachment.tag = indexPath.row;
viewAttachment.accessibilityIdentifier = msgDoc.Url;
viewAttachment.accessibilityLabel = msgDoc.Name;
[cell.viewAttachmentCollection addSubview:viewAttachment];
UIImageView *imgAttachment = [[UIImageView alloc]initWithFrame:CGRectMake(10, 10, 52, 60)];
imgAttachment.image = [UIImage imageNamed:#"document.png"];
[viewAttachment addSubview:imgAttachment];
UILabel *lblFileName = [[UILabel alloc]initWithFrame:CGRectMake(65, 5, viewAttachment.frame.size.width - 65, 22)];
lblFileName.backgroundColor = [UIColor clearColor];
lblFileName.text = msgDoc.Name;
lblFileName.text = [lblFileName.text stringByReplacingOccurrencesOfString:#"%20" withString:#" "];
lblFileName.textAlignment = NSTextAlignmentLeft;
lblFileName.font = [UIFont systemFontOfSize:10];
lblFileName.numberOfLines = 0;
[viewAttachment addSubview:lblFileName];
[lblFileName sizeToFit];
UILabel *lblFileType = [[UILabel alloc]initWithFrame:CGRectMake(65, 30, viewAttachment.frame.size.width - 65, 20)];
lblFileType.backgroundColor = [UIColor clearColor];
lblFileType.text = msgDoc.Name;
lblFileType.textAlignment = NSTextAlignmentLeft;
lblFileType.font = [UIFont systemFontOfSize:10];
[viewAttachment addSubview:lblFileName];
UILabel *lblDownload = [[UILabel alloc]initWithFrame:CGRectMake(65, 53, viewAttachment.frame.size.width - 65, 20)];
lblDownload.backgroundColor = [UIColor clearColor];
lblDownload.text = NSLocalizedString(#"click_to_download", nil);
lblDownload.textAlignment = NSTextAlignmentLeft;
lblDownload.font = [UIFont systemFontOfSize:10];
[viewAttachment addSubview:lblDownload];
UITapGestureRecognizer *gestureAttachment = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleAttachmentGesture:)];
[viewAttachment addGestureRecognizer:gestureAttachment];
yAxis = yAxis + 90;
yAxisDocAttachment = yAxisDocAttachment + 90;
cell.viewAttachmentHeightConstraint.constant = cell.viewAttachmentHeightConstraint.constant + 90;
}
}
cell.viewImageHeightConstraint.constant = 0;
if(indexPath.row != 0)
cell.viewImageLeftConstraint.constant = xAxis - 16;
else
cell.viewImageLeftConstraint.constant = xAxis;
for(MessageAttachment *msgDoc in thread.attachments)
{
if([msgDoc.Type isEqual:#"Image"])
{
isImage = YES;
cell.viewImageCollection.hidden = NO;
cell.viewImageTopConstraint.constant = 10;
cell.btnReplyTopConstraint.constant = 10;
[self createAttachmentImage:CGRectMake(xAxis, cell.viewImageHeightConstraint.constant + 10, self.view.frame.size.width - xAxis - 5, 480) cell:cell message:msgDoc indexPath:indexPath];
cell.viewImageHeightConstraint.constant = cell.viewImageHeightConstraint.constant + 5;
}
}
}
if(!isDoc)
{
cell.viewAttachmentCollection.hidden = YES;
cell.viewAttachmentHeightConstraint.constant = 0;
cell.viewAttachmentTopConstraint.constant = 0;
}
if(!isImage)
{
cell.viewImageCollection.hidden = YES;
cell.viewImageHeightConstraint.constant = 0;
cell.viewImageTopConstraint.constant = 0;
}
[cell.btnReplyCell setTitle:[NSString stringWithFormat:#"%# %#", NSLocalizedString(#"reply", nil),thread.sender.FirstName] forState:UIControlStateNormal];
[cell.btnReplyCell setTitle:[NSString stringWithFormat:#"%# %#", NSLocalizedString(#"reply", nil),thread.sender.FirstName] forState:UIControlStateDisabled];
[cell.btnReplyCell setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[cell.btnReplyCell setTitleColor:[UIColor colorWithRed:199.0/255.0 green:192.0/255.0 blue:193.0/255.0 alpha:1.0] forState:UIControlStateDisabled];
if(thread.sender.SenderId != [[NSString stringWithFormat:#"%#", [[NSUserDefaults standardUserDefaults]objectForKey:#"UserId"]] intValue])
{
cell.btnReplyTopConstraint.constant = 10;
cell.btnReplyHeightConstraint.constant = 30;
cell.btnReplyBottomConstraint.constant = 12;
cell.btnReplyCell.titleLabel.textAlignment = NSTextAlignmentCenter;
cell.btnReplyCell.layer.cornerRadius = 7;
cell.btnReplyCell.tag = (int)indexPath.row;
cell.btnReplyCell.backgroundColor = [UIColor whiteColor];
cell.btnReplyCell.layer.borderColor = [[UIColor blackColor] CGColor];
cell.btnReplyCell.layer.borderWidth = 0.7;
cell.btnReplyCell.accessibilityIdentifier = [NSString stringWithFormat:#"%i", (int)arrBtnReply.count];
cell.btnReplyCell.titleLabel.font = [UIFont systemFontOfSize:12];
[cell.btnReplyCell addTarget:self action:#selector(replyTapped:) forControlEvents:UIControlEventTouchUpInside];
yAxis = yAxis + 20;
cell.btnReplyCell.accessibilityLabel = [NSString stringWithFormat:#"%f", yAxis];
cell.btnReplyCell.enabled = YES;
cell.btnReplyTopConstraint.constant = 10;
}
else
{
cell.btnReplyTopConstraint.constant = 10;
cell.btnReplyBottomConstraint.constant = 0;
cell.btnReplyCell.hidden = YES;
cell.btnReplyHeightConstraint.constant = 0;
cell.btnReplyCell.layer.cornerRadius = 7;
cell.btnReplyCell.backgroundColor = [UIColor colorWithRed:224.0/255.0 green:224.0/255.0 blue:224.0/255.0 alpha:1.0];
cell.btnReplyCell.enabled = NO;
}
[cell updateConstraintsIfNeeded];
[cell setNeedsLayout];
[cell layoutIfNeeded];
return cell;
}
}
#catch (NSException *exception) {
return cell;
}
}
I know that huge code, but what would be interrupting the smooth scroll ?
I describe a few assumptions:
You configure many constraints. It's bad for smooth scrolling. If your cell is complex and thus there are many contraints -> you can see twitching scroll.
Also I can see that you dynamically add / remove subview. Why do you do this? Why don't you configure label in the init method?
Sometimes shadow and cornerRadius can affect on smooth scrolling.
I think in your case main problem - it's constraints and dynamic add/deleting views.
I have added UISegmentedController to TableViewCell in CellForRowAtIndexPath.
Following is the code.
[cell.segStatus addTarget:self action:#selector(selectedSegmentControl:) forControlEvents: UIControlEventValueChanged];
[cell.segStatus setSegmentedControlStyle:UISegmentedControlStyleBar];
cell.segStatus.tag = indexPath.row;
I use UITableViewCell class for customized class.
I select segment and when I scroll the tableview some other cell's segmented controller also automatically select.
Why is it? how can I sort out this ?
Full CellForRowAtIndexPath Method
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
#try {
static NSString *defTableIdentifier = #"DefectRegisterCell";
DefectRegisterCell *cell = (DefectRegisterCell *)[self.tblDefectList dequeueReusableCellWithIdentifier:defTableIdentifier];
_defectEntry = [defectObjList objectAtIndex:indexPath.row];
cell.lblDefectNo.text = [NSString stringWithFormat:#"%#", _defectEntry.defectNo];
if ([_defectEntry.defect isEqual:#"None"] || [_defectEntry.defect isEqual:#""] ) {
cell.lblDefect.text = [NSString stringWithFormat:#"%# - %# - Passed", _defectEntry.item,_defectEntry.subItem];
}
else{
cell.lblDefect.text = [NSString stringWithFormat:#"%# - %# - %#", _defectEntry.item,_defectEntry.subItem,_defectEntry.defect];
}
cell.lblLocation.text = #"Location:";
cell.lblLocationValue.text = [NSString stringWithFormat:#"%# > %# > %# > %# (%# - %#)",_defectEntry.building, _defectEntry.area, _defectEntry.location, _defectEntry.room,_defectEntry.orient, _defectEntry.position];
cell.lblAssignedTo.text = #"Assigned to:";
cell.lblAssignedToValue.text = _defectEntry.responsibleComp;
cell.lblDue.text = #"Due:";
cell.lblDueValue.text = _defectEntry.dueDate;
cell.lblCapturedBy.text = #"Recorded by:";
cell.lblCapturedByValue.text = [NSString stringWithFormat:#"%# (%#)",_defectEntry.inspectedId,_defectEntry.inspectedCompId];
cell.lblDate.text = #"On:";
cell.lblDateValue.text = _defectEntry.createdDate;
NSString *attached = #"0" ;
NSString *fixClaimed = #"0";
NSString *completed = #"0";
if ([_defectEntry.attached length] > 0) {
attached = #"1";
}
if ([_defectEntry.fixClaimed isEqualToString:#"Y"]) {
fixClaimed = #"1";
}
if ([_common checkDateValidation:_defectEntry.completed]) {
completed = #"1";
}
[cell.segStatus addTarget:self action:#selector(selectedSegmentControl:) forControlEvents: UIControlEventValueChanged];
[cell.segStatus setSegmentedControlStyle:UISegmentedControlStyleBar];
cell.segStatus.tag = indexPath.row;
if ([attached isEqualToString:#"1"]) {
cell.imgAttachment.image = [UIImage imageNamed:#"diAttachments.png"];
}
if ([fixClaimed isEqualToString:#"1"]) {
cell.imgDefect.image = [UIImage imageNamed:#"diWarning.png"];
cell.segStatus.hidden = NO;
} else if ([completed isEqualToString:#"1"]) {
cell.imgDefect.image = [UIImage imageNamed:#"diRight.png"];
if ([_defectEntry.passed isEqualToString:#"Yes"]) {
cell.segStatus.hidden = YES;
}
else{
cell.segStatus.hidden = NO;
}
} else {
cell.imgDefect.image = [UIImage imageNamed:#"diWrong.png"];
cell.segStatus.hidden = NO;
}
UIView *backgroundView = [[UIView alloc] init];
if (indexPath.row % 2) {
backgroundView.backgroundColor = [UIColor whiteColor];
} else {
backgroundView.backgroundColor = [UIColor colorWithRed:242/255.0f green:242/255.0f blue:242/255.0f alpha:1.0f];
}
cell.backgroundView = backgroundView;
//change the selected cell color
UIView *selectedBackgroundView = [[UIView alloc] init];
selectedBackgroundView.backgroundColor = gaSelectedColor;
cell.selectedBackgroundView = selectedBackgroundView;
return cell;
}
#catch(NSException *excp)
{
NSLog(#"%#",excp);
}
}
in my tableview I have a button in the custom cell
I used the delegates to take an action to the button
The button image changes only on the selected cell
My problem is this:
When I press the button happens:
the selected cell is working properly and the button changes correctly (correct)
the second immediately after the selected cell does not change the button (corrected)
the third cell repeats the action of the selected cell (wrong)
This is repeated endlessly do not understand why
The button should change only the selected cell and not on other non-selected
Can you help me please?
-(void)ButtonPressedGoPoint:(FFCustomCellWithImage *)custom button:(UIButton *)gopointpressed {
NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
[numberFormatter setLocale:[[NSLocale alloc] initWithLocaleIdentifier:#"it_IT"]];
NSNumber *likeCount = [numberFormatter numberFromString:custom.CountGoPoint.text];
if (!custom.AddGoPoint.selected) {
NSLog(#"TastoSelezionato");
likeCount = [NSNumber numberWithInt:[likeCount intValue] + 1];
custom.CountGoPoint.text = [NSString stringWithFormat:#"%#", likeCount];
[custom.AddGoPoint setBackgroundImage:[UIImage imageNamed:#"FFIMG_Medal_Blu"] forState:UIControlStateNormal];
}
else {
if ([likeCount intValue] > 0) {
likeCount = [NSNumber numberWithInt:[likeCount intValue] - 1];
custom.CountGoPoint.text = [NSString stringWithFormat:#"%#", likeCount];
}
NSLog(#"TastoDeselezionato");
[custom.AddGoPoint setBackgroundImage:[UIImage imageNamed:#"FFIMG_MedalADD"] forState:UIControlStateNormal];
}
custom.AddGoPoint.selected = !custom.AddGoPoint.selected;
}
This is my implementation of the tableview
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
self.PostDetails = [ArrayforPost objectAtIndex:indexPath.row];
static NSString *IdentificazioneCellaIMG = #"CellaIMG";
FFCustomCellWithImage * CellaIMG = (FFCustomCellWithImage * )[self.FFTableView dequeueReusableCellWithIdentifier:IdentificazioneCellaIMG];
if (CellaIMG == nil) {
CellaIMG = [[FFCustomCellWithImage alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:IdentificazioneCellaIMG ];
}
CellaIMG.delegate = self;
CellaIMG.tag = indexPath.row;
[CellaIMG.AddGoPoint setTag:indexPath.row];
if ([self AssignedGoPointToPost:self.PostDetails]) {
CellaIMG.AddGoPoint.selected =YES;
[CellaIMG.AddGoPoint setImage:[UIImage imageNamed:#"FFIMG_Medal_Blu"] forState:UIControlStateNormal];
} else {
CellaIMG.AddGoPoint.selected =NO;
[CellaIMG.AddGoPoint setImage:[UIImage imageNamed:#"FFIMG_MedalADD"] forState:UIControlStateNormal];
}
NSString *FotoPostSocial = [self.PostDetails objectForKey:FF_POST_IMMAGINE];
CellaIMG.FotoPost.file = (PFFile *)FotoPostSocial;
[CellaIMG.FotoPost loadInBackground];
CellaIMG.FotoPost.layer.masksToBounds = YES;
CellaIMG.FotoPost.layer.cornerRadius = 2.0f;
CellaIMG.FotoPost.contentMode = UIViewContentModeScaleAspectFill;
CellaIMG.backgroundCell.layer.masksToBounds = YES;
CellaIMG.backgroundCell.layer.cornerRadius = 2.0f;
CellaIMG.backgroundCell.layer.borderColor = [UIColor colorWithRed:(219/255.0) green:(219/255.0) blue:(219/255.0) alpha:(1)].CGColor;
CellaIMG.backgroundCell.layer.borderWidth = 1.0f;
CellaIMG.backgroundCell.autoresizingMask = UIViewAutoresizingFlexibleHeight;
CellaIMG.LeggiCommentoButton.layer.cornerRadius = 2.0f;
CellaIMG.FotoProfilo.layer.masksToBounds = YES;
CellaIMG.FotoProfilo.layer.cornerRadius = 25.0f;
CellaIMG.FotoProfilo.contentMode = UIViewContentModeScaleAspectFill;
CellaIMG.TestoPost.font = [UIFont fontWithName:#"Helvetica" size:14.0f];
NSString *text = [self.PostDetails objectForKey:FF_POST_TEXT];
CellaIMG.TestoPost.text = text;
[CellaIMG.TestoPost setLineBreakMode:NSLineBreakByTruncatingTail];
NSString *NomeUser = [[self.PostDetails objectForKey:FF_POST_UTENTE] objectForKey:FF_USER_NOMECOGNOME];
CellaIMG.NomeUtente.text = NomeUser;
NSString *ImmagineUtente = [[self.PostDetails objectForKey:FF_POST_UTENTE] objectForKey:FF_USER_FOTOPROFILO];
CellaIMG.FotoProfilo.file = (PFFile *)ImmagineUtente;
[CellaIMG.FotoProfilo loadInBackground];
if (CellaSelezionata == indexPath.row) {
CGFloat AltezzaLabel = [self valoreAltezzaCella: indexPath.row];
CellaIMG.TestoPost.frame = CGRectMake(CellaIMG.TestoPost.frame.origin.x, CellaIMG.TestoPost.frame.origin.y, CellaIMG.TestoPost.frame.size.width, AltezzaLabel); }
else {
CellaIMG.TestoPost.frame = CGRectMake(CellaIMG.TestoPost.frame.origin.x, CellaIMG.TestoPost.frame.origin.y, CellaIMG.TestoPost.frame.size.width, 65);
}
return CellaIMG;
}
}
am getting the following error while scrolling the UITableview.
EXC_BAD_ACCESS, -[CFString retain]: message sent to deallocated instance
how can i find the deallocated instance...?
this my noOfRowsinsection code
for(int i=0;i<size;i++)
{
NSString *CellIdentifier1;
if(universalApp==2)
{
NSAutoreleasePool *pool=[[NSAutoreleasePool alloc]init];
CellIdentifier1 = #"CustomThumbImageTableCell_iphone";
cell = [[[CustomThumbImageTableCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier1] autorelease];
//NSLog(#">>>>> Creating image >>>>>>>>");
//cell.thumbImageView = [[CustomImageView alloc] initWithFrame:CGRectMake(4, 4, 83, 101)];
cell.thumbImageView = [[[CustomImageView alloc] initWithFrame:CGRectMake(4, 4, 83, 101)] autorelease];
[imgViewArray addObject:cell.thumbImageView];
[cell.thumbImageView release];
[pool release];
}
and this my cellforRow code
enter code hereif(universalApp==2)
{
NSLog(#"iphone cell>>>>>>>>>>>>>>>>>>>>>>");
CustomThumbImageTableCell *cell = nil;
#try
{
static NSString *CellIdentifier = #"CustomThumbImageTableCell_iphone";
int currentRow = [indexPath row] ;//+ skippedItems;
//NSLog(#">>>>>>>>>>>>Current Table row = %d, %d, %d", loadedCellArray.count, currentRow, [Table numberOfRowsInSection:0]);
/*if(loadedCellArray.count > currentRow + 1 && [loadedCellArray objectAtIndex:(currentRow)] != nil)
{
NSLog(#"Image updated = %d", ( currentRow));
cell = (CustomThumbImageTableCell_iphone *) [loadedCellArray objectAtIndex:(currentRow )];
}
else
{*/
/*if(loadedCellArray.count > currentRow + 1 )// && [loadedCellArray objectAtIndex:(currentRow)] != nil)
// if( [loadedCellArray objectAtIndex:(currentRow)] != nil)
{
//NSLog(#"Image updated = %d", ( currentRow));
cell = (CustomThumbImageTableCell_iphone *) [loadedCellArray objectAtIndex:([indexPath row] )];
if(!isScrollingUp)
{
//scrollCount++;
[loadedCellArray removeLastObject];
}
isScrollingUp = YES;
}
else*/
{
static NSString *CellIdentifier = #"CustomThumbImageTableCell_iphone";
static NSString *CellIdentifier1 = #"CustomThumbImageTableCell_iphone";
//UITableViewCell *cell;
if(cell==nil)
{
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
cell = [[[CustomThumbImageTableCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
}
else
{
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier1];
cell = [[[CustomThumbImageTableCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier1] autorelease];
}
cell.selectionStyle = UITableViewCellSelectionStyleNone;
NSLog(#">>>>>>>>>..... %d, %d, %#", imgViewArray.count, indexPath.row, (((int)imgViewArray.count- 1) < (int)indexPath.row) ? #"YES" : #"NO");
/*if(((int)imgViewArray.count- 1) < (int)indexPath.row)
{
// NSLog(#">>>>> Creating image >>>>>>>>");
cell.thumbImageView = [[CustomImageView alloc] initWithFrame:CGRectMake(4, 4, 83, 101)];
[imgViewArray addObject:cell.thumbImageView];
}
else {
cell.thumbImageView = (CustomImageView *) [imgViewArray objectAtIndex:indexPath.row];
}*/
//NSLog(#"img array = %#,%d",imgViewArray,imgViewArray.count);
cell.thumbImageView =[imgViewArray objectAtIndex:indexPath.row];
cell.thumbImageView.contentMode = UIViewContentModeScaleAspectFit;
[cell.contentView addSubview:cell.thumbImageView];
cell.thumbImageView.index = (int)indexPath.row;
#try
{
{
BOOL isFound = NO;
do
{
#try {
NSArray *array1 = [contentString componentsSeparatedByString:#"###"];
NSArray *array2 = [[array1 objectAtIndex:currentRow ] componentsSeparatedByString:#"##"];
NSString *str = [NSString stringWithFormat:#"%#", [array2 objectAtIndex:0]];
str = [str stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
UILabel *name = [[UILabel alloc] initWithFrame:CGRectMake(104, 6, 141, 96)];
name.textAlignment = UITextAlignmentCenter;
name.font = [UIFont fontWithName:#"Arial" size:17.0];
name.numberOfLines = 3;
name.backgroundColor = [UIColor clearColor];
name.textColor = [UIColor whiteColor];
cell.catalogName = name;
[cell.catalogName setText:[NSString stringWithFormat:#"%#", str]];
[cell.contentView addSubview:cell.catalogName];
//[name release];
name = [[UILabel alloc] initWithFrame:CGRectMake(107, 89, 193, 21)];//107,89,193
name.textAlignment = UITextAlignmentCenter;
name.font = [UIFont fontWithName:#"Arial" size:13.0];
name.textColor = [UIColor whiteColor];
name.numberOfLines = 3;
name.backgroundColor = [UIColor clearColor];
name.alpha = 0.26;
cell.pageNo = name;
[cell.contentView addSubview:cell.pageNo];
//[name release];
if((searchId != 2 && (isLineNameSearchEnabled == 0)) || searchInCatalogFlag == 1)
//cell Page No//pageNoLabel
//NSLog(#"cell for row.......");
[cell.pageNo setText:[NSString stringWithFormat:#"Page No: %#", [array2 objectAtIndex:(array2.count - 2)]]];
{
}
NSLog(#" thumb image = %#",[NSString stringWithFormat:#"%#%#", baseURL, [array2 objectAtIndex:1]]);
//[cell.thumbImageView setImageURL:#"http://www.zoomcatalog.com/sites/default/files/catalogs/27705_Abex2010/images/thumbnails/Thumb-1.jpg"];
[cell.thumbImageView setImageURL:[NSString stringWithFormat:#"%#%#", baseURL, [array2 objectAtIndex:1]]];
[NSThread detachNewThreadSelector:#selector(initThread) toTarget:cell.thumbImageView withObject:nil];
[cell.thumbImageView setPageNo:((searchId == 2 || (isLineNameSearchEnabled && searchInCatalogFlag == 0)) ? 0 : (int)currentRow)];
UIImageView *img = [[UIImageView alloc] initWithFrame:CGRectMake(264, 33, 36, 34)];
img.contentMode = UIViewContentModeScaleToFill;
[img setImage:cellArrow];
[cell.contentView addSubview:img];
[img release];
[cell.catalogName release];
//>>>> [cell.pageNoLabel release];
[cell.thumbImageView release];
isFound = YES;
}
#catch (NSException * e) {
//skippedItems++;
currentRow = [indexPath row] + 1;
}
}
while (!isFound);
/*if(isScrollingUp)
{
//scrollCount++;
[loadedCellArray removeLastObject];
}
isScrollingUp = NO;
currentRow =indexPath.row;
// cell = (CustomThumbImageTableCell_iphone *) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
//cell = (CustomThumbImageTableCell_iphone *) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"CustomThumbImageTableCell_iphone" owner:self options:nil];
//cell = (CustomThumbImageTableCell_iphone *) [loadedCellArray objectAtIndex:(currentRow )];
cell = self.cell;
self.cell = nil;
}
NSLog(#"Image loaded from source= %d,", ( currentRow));
//if(loadedCellArray.count > currentRow + 1)
// NSLog(#"Image loaded from source cell array ref= %#", [loadedCellArray objectAtIndex:(currentRow)]);
/*if(currentRow == ([Table numberOfRowsInSection:0] - 1))
{
cell.catalogName.text = #"50 More";
NSLog(#">>>>>>>>>>>>>>>>>>>>> End cell....");
return cell;
}
/////
// if(true)
// return cell;
#try
{
{
BOOL isFound = NO;
do
{
#try {
NSArray *array1 = [contentString componentsSeparatedByString:#"###"];
NSArray *array2 = [[array1 objectAtIndex:currentRow] componentsSeparatedByString:#"##"];
NSString *str = [NSString stringWithFormat:#"%#", [array2 objectAtIndex:0]];
str = [str stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
// NSLog(#"&&&&&&&&&&&&&&&&& %#", str);
[cell.catalogName setText:[NSString stringWithFormat:#"%#", str]];
if((searchId != 2 && (isLineNameSearchEnabled == 0)) || searchInCatalogFlag == 1)
[cell.pageNo setText:[NSString stringWithFormat:#"Page No: %#", [array2 objectAtIndex:(array2.count - 2)]]];
// NSLog(#"Background color has been set....%d", i);
//NSLog(#")
//NSLog(#"Catalog %d = %#", currentRow, [array1 objectAtIndex:currentRow]);
// NSLog(#"Image URL = %#", [NSString stringWithFormat:#"%#%#", baseURL, [array2 objectAtIndex:1]]);
[cell.thumbImageView setImageURL:[NSString stringWithFormat:#"%#%#", baseURL, [array2 objectAtIndex:1]]];
//[cell.thumbImageView setContentString:contentString];
//if(searchId == 2)
// [cell.thumbImageView setContentString:[NSString stringWithFormat:#"%#", [array2 objectAtIndex:(array2.count - (isLineNameSearch ? 2 : 2))]]];
[cell.thumbImageView performSelectorOnMainThread:#selector(initThread) withObject:nil waitUntilDone:NO];
[cell.thumbImageView setPageNo:(searchId == 2 ? #"0" : [indexPath row])];
isFound = YES;
}
#catch (NSException * e) {
//skippedItems++;
currentRow = [indexPath row] + 1;
}
*/
// }
// while(!isFound);// && currentRow < [Table numberOfRowsInSection:0]);
//[imgViewArray addObject:cell.thumbImageView];
// [imgViewArray retain];
//[label setTextColor:[UIColor blackColor]];
//[label setTextAlignment:UITextAlignmentCenter];
/* UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(7 + ((i % 3) * (96 + 8)) , 9 + ((i / 3) * (140 + 10)), 98, 142)];
[label setBackgroundColor:[UIColor grayColor]];
[scrollView addSubview:label];
[imgViewArray addObject:imgView];
[scrollView addSubview:imgView];
if(i % 3 == 0)
{
[scrollView setContentSize:CGSizeMake(scrollView.contentSize.width, scrollView.contentSize.height + (140 + 10))];
}*/
}
//[imgViewArray retain];
// [cellArray retain];
}
When you have memory management issues, there are a number of things you can do:
Re-read the Cocoa memory management rules and make sure that you're following them.
Run the static analyser. This will often pick up places where you have neglected the memory management rules.
Since it appears that you have already enabled NSZombies, insert a breakpoint for [_NSZombie release]. This should hopefully break on the line that is causing the problem.
Edit:
Based on your code, the following line could be the culprit.
[cell.thumbImageView release]; // NOT GOOD
Similarly in your other code you have:
[cell.thumbImageView release]; // NOT GOOD
[cell.catalogName release]; // NOT GOOD
You set an autoreleased object to the thumbImageView and catalogName property of the cell, but you are still trying to release it. This is not how Cocoa memory management works. You don't own cell.thumbImageView or cell.catalogName, so you should not release them.
This problem occurs when you are trying to access the deallocated object. May be your string get released before you accessing it.
I update the table view cell using the method below:
- (void)imageDownloader:(SDWebImageDownloader *)downloader didFinishWithIndexPath:(NSIndexPath *)indexPath
{
NSArray *arr = [self.tableView indexPathsForVisibleRows];
if ([arr containsObject:indexPath])
{
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];//received error here
UIImageView *imageView = (UIImageView *)[cell viewWithTag:'ICON'];
SDWebImageManager *manager = [SDWebImageManager sharedManager];
UIImage *image = [manager imageWithURL:downloader.url];
imageView.image = image;
}
}
This is a delegate of SDWebImageDownloader and received error when update:
thread9: Program received signal: "SIGABRT".
Form the device console, there is:
: *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayM objectAtIndex:]: index 7 beyond bounds [0 .. 6]'
*** First throw call stack:
(0x335a38bf 0x300971e5 0x334ecb6b 0x30ff0eb1 0xaa0a7 0x334fd435 0xb5b13 0x30d91a91 0x30e255a1 0x36fa0c1d 0x36fa0ad8)
Then I print the arr which holds the current visible index path:
Printing description of arr:
(
" 2 indexes [0, 1]",
" 2 indexes [0, 2]",
" 2 indexes [0, 3]",
" 2 indexes [0, 4]",
" 2 indexes [0, 5]",
" 2 indexes [0, 6]",
" 2 indexes [0, 7]"
)
and the received indexPath
2 indexes [0, 7]
The indexPath is included in the visible index path, and why it still cause the NSRangeException?
It looks like a bug for cellForRowAtIndexPath:indexPath, as the row of index path is 7 which is beyond the visible index path arr, am I right?
Add the eatableview delegate method:
- (UITableViewCell *)tableView:(UITableView *)inTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
NSString *path;
NSString *filename;
BOOL download = YES;
NSDictionary *tempDic = nil;
#synchronized (documentDirectoryFileList) {
tempDic = [self.documentDirectoryFileList objectAtIndex:indexPath.row];
filename = [tempDic objectForKey:#"filename" ];
NSURL *url = [tempDic objectForKey:#"url" ];
if ( url ) {
path = [ url path ];
download= [ self downloadedFile:url ];
} else {
path = [tempDic objectForKey:#"filepath" ];
}
}
BOOL isDirectory = FALSE;
NSFileManager *fileManager = [[NSFileManager alloc] init];
BOOL found = [fileManager fileExistsAtPath: path isDirectory: &isDirectory];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
CGRect rect;
rect = CGRectMake(5,14, 32, 32);
cell.userInteractionEnabled = YES;
UIImageView *imageView = [[UIImageView alloc] initWithFrame:rect];
imageView.tag = 'ICON';
[cell.contentView addSubview:imageView];
[imageView release];
rect = CGRectMake(42, 10, 238, 22);
UILabel *labelView = [[UILabel alloc] initWithFrame:rect];
labelView.tag = 'NAME';
labelView.font = [UIFont boldSystemFontOfSize:18];
if ( download == NO )
labelView.textColor = [UIColor lightGrayColor ];
[cell.contentView addSubview:labelView];
[labelView release];
rect = CGRectMake(42, 34, 200, 20);
labelView = [[UILabel alloc] initWithFrame:rect];
labelView.tag = 'TIME';
labelView.font = [UIFont systemFontOfSize:12];
if ( download == NO )
labelView.textColor = [UIColor lightGrayColor ];
[cell.contentView addSubview:labelView];
[labelView release];
rect = CGRectMake(200, 34, 75, 20);
labelView = [[UILabel alloc] initWithFrame:rect];
labelView.tag = 'SIZE';
labelView.font = [UIFont systemFontOfSize:12];
if ( download == NO )
labelView.textColor = [UIColor lightGrayColor ];
labelView.textAlignment = UITextAlignmentRight;
[cell.contentView addSubview:labelView];
[labelView release];
}
// Get the time zone wrapper for the row
UIImageView *imageView = (UIImageView *)[cell viewWithTag:'ICON'];
imageView.image = NULL;
NSString* extension = [[path pathExtension] lowercaseString];
if ([extension isEqualToString: #"png"] ||
[extension isEqualToString: #"jpg"] ||
[extension isEqualToString: #"jpeg"] ||
[extension isEqualToString: #"bmp"] ||
[extension isEqualToString: #"gif"] ||
[extension isEqualToString: #"tiff"] ||
[extension isEqualToString: #"thm"])
{
NSString *realFilePath = [ fileManager destinationOfSymbolicLinkAtPath:path error:nil ];
if ( realFilePath )
path = realFilePath;
NSURL *url = [[NSURL fileURLWithPath:path] URLByAppendingPathComponent:#"thumb.th"];
SDWebImageManager *manager = [SDWebImageManager sharedManager];
UIImage *temp = [manager imageWithURL:url];
if (temp) {
imageView.image = temp;
}
else
{
SDWebImageDownloader *downloader = [SDWebImageDownloader downloaderWithURL:url delegate:self indexPath:indexPath];
}
} else {
imageView.image = [ self determineFileIcon : path ];
}
// Configure the cell.
UILabel *labelView = (UILabel *)[cell viewWithTag:'NAME'];
labelView.text = filename;
cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;
if ( isDirectory ) {
if ( isLink( path ) )
labelView.font = [UIFont italicSystemFontOfSize:16.0];
else
labelView.font = [UIFont boldSystemFontOfSize:16.0];
} else {
if ( isLink( path ) )
labelView.font = [UIFont italicSystemFontOfSize:16.0];
else
labelView.font = [UIFont systemFontOfSize:16.0];
}
labelView = (UILabel *)[cell viewWithTag:'TIME'];
NSCalendar *theCalendar= [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSCalendarUnit unitFlags = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit;
NSDate *date = [tempDic objectForKey:#"date" ];
NSDateComponents *dateComponents = [theCalendar components:unitFlags fromDate:date];
NSInteger year = [dateComponents year];
NSInteger month = [dateComponents month];
NSInteger day = [dateComponents day];
NSInteger hour = [dateComponents hour];
NSInteger minute = [dateComponents minute];
NSInteger second = [dateComponents second];
[theCalendar release];
labelView.text = [NSString stringWithFormat:#"%d/%02d/%02d %02d:%02d:%02d", year,month,day,hour,minute,second ];
if ( !isDirectory ) {
labelView = (UILabel *)[cell viewWithTag:'SIZE'];
[labelView setHidden:NO];
NSNumber *size = [tempDic objectForKey:#"filesize" ];
float value = [ size floatValue ];
NSString *str;
if ( value > ( 1024*1024 ) ) {
value = value / 1024 / 1024;
str = [NSString stringWithFormat:#"%0.1f MB", value ];
} else if ( value > 1024 ) {
value = value / 1024;
str = [NSString stringWithFormat:#"%0.1f KB", value ];
} else {
str = [NSString stringWithFormat:#"%d Bytes", [ size integerValue ] ];
}
labelView.text = str;
}
else
{
labelView = (UILabel *)[cell viewWithTag:'SIZE'];
[labelView setHidden:YES];
}
[fileManager release];
return cell;
}
Added on 11-17:
when the "SIGABRT" receives, the documentDirectoryFileList has the objects, for example 30+. The received indexPath is existed in the visible index path array. But I noticed that: it is easy to happen when I scroll the tableview. There is no new object added to the datasource. what I do is just updating the image on the cell.
I guess it maybe:
when the received index path begin to update the corresponding cell, I happen to scroll it and the cell or the indexpath is no longer visible. And then it crashes.
It seems a kind of problem about multithread.
- (void)imageDownloader:(SDWebImageDownloader *)downloader didFinishWithIndexPath:(NSIndexPath *)indexPath
{
#synchronized(tableView)
{
NSArray *arr = [self.tableView indexPathsForVisibleRows];
if ([arr containsObject:indexPath])
{
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
if (!cell)
{
return;
}
UIImageView *imageView = (UIImageView *)[cell viewWithTag:'ICON'];
SDWebImageManager *manager = [SDWebImageManager sharedManager];
UIImage *image = [manager imageWithURL:downloader.url];
if (image) {
dispatch_async(dispatch_get_main_queue(), ^{
imageView.image = image;
});
}
}
}
}
or you can
- (void)imageDownloader:(SDWebImageDownloader *)downloader didFinishWithIndexPath:(NSIndexPath *)indexPath
{
#synchronized(tableView)
{
NSArray *arr = [self.tableView indexPathsForVisibleRows];
if ([arr containsObject:indexPath])
{
dispatch_async(dispatch_get_main_queue(), ^{
[self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObjects:indexPath, nil] withRowAnimation:UITableViewRowAnimationNone];
});//must be in main thread; reloadRowsAtIndexPaths: is not thread safe
}
}
}