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
}
}
}
Related
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.
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.
My app is scrolling and Searching very slow when I have Images set for each cell.Pictures lifted faster, but still slow when searching. Here is my code in the cell at row. Any ideas?
#interface UIImage (TPAdditions)
- (UIImage*)imageScaledToSize:(CGSize)size;
#end
#implementation UIImage (TPAdditions)
- (UIImage*)imageScaledToSize:(CGSize)size {
UIGraphicsBeginImageContext(size);
[self drawInRect:CGRectMake(0, 0, size.width, size.height)];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
#end
cellForRowAtIndexPath
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
static NSInteger buton1_tag = 100;
static NSInteger buton2_tag = 101;
if (indexPath.section == 0) {
CellIdentifier = #"CellMuzikEkle";
}else{
if(indexPath.row == 0 && !self.editing)
CellIdentifier = #"CellPlayereEkle";
else
CellIdentifier = #"CellDizi";
}
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
if (indexPath.section == 1 && indexPath.row == 0 && !self.editing) // Grubu ekle
cell = [[[NSBundle mainBundle] loadNibNamed:#"Cell4" owner:self options:nil] objectAtIndex:0];
else{
if (indexPath.section == 0) {
cell = [[[NSBundle mainBundle] loadNibNamed:#"Cell" owner:self options:nil] objectAtIndex:5];
UIButton *ipodbuton = (UIButton *) [cell.contentView viewWithTag:buton1_tag];
[ipodbuton addTarget:self action:#selector(iPoddan_Ekle:) forControlEvents:UIControlEventTouchUpInside];
UIButton *yuklenenler = (UIButton *) [cell.contentView viewWithTag:buton2_tag];
[yuklenenler addTarget:self action:#selector(Yuklenenlerden_Ekle:) forControlEvents:UIControlEventTouchUpInside];
}else{
cell.textLabel.font = [UIFont boldSystemFontOfSize:15.0];
cell.textLabel.numberOfLines=2;
cell.detailTextLabel.font = [UIFont systemFontOfSize:13];
[cell.imageView.layer setBorderWidth: 1.5];
}
}
}
if (indexPath.section == 1 && !self.editing && indexPath.row != 0)
cell.accessoryType =UITableViewCellAccessoryDetailDisclosureButton;
else
cell.accessoryType =UITableViewCellAccessoryNone;
if(indexPath.section == 0){
cell.textLabel.text = #"";
cell.detailTextLabel.text = #"";
cell.imageView.image = nil;
}else{
if (indexPath.row > 0 || self.editing) {
if (!self.editing)
indexPath = [NSIndexPath indexPathForRow:indexPath.row - 1 inSection:indexPath.section];
NSArray *aradizi = tableView == self.searchDisplayController.searchResultsTableView ? [[NSArray alloc] initWithArray:self.filteredListContent] : [[NSArray alloc] initWithArray:self.dizi];
if ([[NSUserDefaults standardUserDefaults] boolForKey:cellresimyuk_s])
cell.imageView.image = [[self Resim_Artwork:[aradizi objectAtIndex:indexPath.row]] imageScaledToSize:CGSizeMake(65, 50)];
else
cell.imageView.image = nil;
cell.textLabel.text = [[aradizi objectAtIndex:indexPath.row] objectForKey:isim_s];
NSTimeInterval theTimeInterval = [[[aradizi objectAtIndex:indexPath.row] objectForKey:sure_s] intValue] - 1;
NSDateFormatter* dateFormatter = [[NSDateFormatter alloc] init];
NSDate *date1;
if (theTimeInterval >= 3600) {
[dateFormatter setDateFormat:#"HH:mm:ss"];
date1 = [dateFormatter dateFromString:#"00:00:00"];
}else{
[dateFormatter setDateFormat:#"mm:ss"];
date1 = [dateFormatter dateFromString:#"00:00"];
}
NSDate *date2 = [[NSDate alloc] initWithTimeInterval:theTimeInterval sinceDate:date1];
cell.detailTextLabel.text = [dateFormatter stringFromDate:date2];
}else{
if (tableView == self.searchDisplayController.searchResultsTableView)
cell.textLabel.text = AramaSonuclrPlayerEkle_lclz;
else
cell.textLabel.text = GrubuPlayereEkle_lclz;
}
}
return cell;
}
Resim_Artwork
- (UIImage *)Resim_Artwork:(NSDictionary *)dictr{
if ([dictr objectForKey:videoid_s]) {
if ([self Dosya_Varmi:[[rsm_favori stringByAppendingPathComponent:[dictr objectForKey:videoid_s]] stringByAppendingPathExtension:#"png"]])
return [UIImage imageWithContentsOfFile:[[rsm_favori stringByAppendingPathComponent:[dictr objectForKey:videoid_s]] stringByAppendingPathExtension:#"png"]];
}else{
if ([[[dictr objectForKey:urlsi_s] pathExtension] isEqualToString:#"mp4"]) {
AVURLAsset *assetresim = [[AVURLAsset alloc] initWithURL:[NSURL fileURLWithPath:[kDocdir stringByAppendingPathComponent:[dictr objectForKey:urlsi_s]]] options:nil];
AVAssetImageGenerator *gen = [[AVAssetImageGenerator alloc] initWithAsset:assetresim];
gen.appliesPreferredTrackTransform = YES;
int suresi = CMTimeGetSeconds(assetresim.duration);
if (suresi > 0) {
CMTime time;
if (suresi>6)
time = CMTimeMakeWithSeconds(6.0, 600);
else
time = CMTimeMakeWithSeconds(0.0, 600);
NSError *error = nil;
CMTime actualTime;
CGImageRef image = [gen copyCGImageAtTime:time actualTime:&actualTime error:&error];
UIImage *thumb = [[UIImage alloc] initWithCGImage:image];
CGImageRelease(image);
return thumb;
}
}else {
if ([dictr objectForKey:kaynak_s]) {
AVAsset *asset = [AVURLAsset URLAssetWithURL:[NSURL URLWithString:[dictr objectForKey:urlsi_s]] options:nil];
for ( AVMetadataItem* item in [asset commonMetadata] ) {
if ([[item commonKey] isEqualToString:#"artwork"] )
if (item.dataValue != nil)
if ([UIImage imageWithData:item.dataValue])
return [UIImage imageWithData:item.dataValue];
}
}else{
if ([self Dosya_Varmi:[kDocdir stringByAppendingPathComponent:[dictr objectForKey:urlsi_s]]]){
AVAsset *asset = [AVURLAsset URLAssetWithURL:[NSURL fileURLWithPath:[kDocdir stringByAppendingPathComponent:[dictr objectForKey:urlsi_s]]] options:nil];
for ( AVMetadataItem* item in [asset commonMetadata] ) {
if ([[item commonKey] isEqualToString:#"artwork"] )
if (item.dataValue != nil)
if ([UIImage imageWithData:item.dataValue])
return [UIImage imageWithData:item.dataValue];
}
}
}
}
}
return [self Resimm:#".varsayilan" Koordinat:CGRectMake(120,1320, 80, 60) retinami:0 grubu:6];
}
tableView willDisplayCell
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
NSArray *viewControllers = [self.tabBarController viewControllers];
NSArray *viewControllers2 = [[viewControllers objectAtIndex:0] viewControllers];
Player *detailViewController = (Player *)[viewControllers2 objectAtIndex:0];
[detailViewController.temalar Cell_Tema:cell];
cell.textLabel.backgroundColor = [UIColor clearColor];
cell.detailTextLabel.backgroundColor = [UIColor clearColor];
cell.textLabel.textColor = [detailViewController.temalar Baslik_Renk];
cell.detailTextLabel.textColor = [detailViewController.temalar Bilgi_Renk];
[cell.imageView.layer setBorderColor: [tableView.separatorColor CGColor]];
[((UIButton *) [cell.contentView viewWithTag:100]) setBackgroundImage:[self Resimm:#".buton" Koordinat:CGRectMake(0,1350, 94, 35) retinami:0 grubu:7] forState:UIControlStateNormal];
[((UIButton *) [cell.contentView viewWithTag:100]) setTitleColor:[detailViewController.temalar Baslik_Renk] forState:UIControlStateNormal];
[((UIButton *) [cell.contentView viewWithTag:101]) setBackgroundImage:[self Resimm:#".buton" Koordinat:CGRectMake(0,1350, 94, 35) retinami:0 grubu:7] forState:UIControlStateNormal];
[((UIButton *) [cell.contentView viewWithTag:101]) setTitleColor:[detailViewController.temalar Baslik_Renk] forState:UIControlStateNormal];
}
Here:
NSArray *aradizi = tableView == self.searchDisplayController.searchResultsTableView ?
[[NSArray alloc] initWithArray:self.filteredListContent] :
[[NSArray alloc] initWithArray:self.dizi];
You should avoid creating objects inside cellForRowAtIndexPath wherever possible.
Anyway you don't need to:
NSArray *aradizi = tableView == self.searchDisplayController.searchResultsTableView ?
self.filteredListContent :
self.dizi;
Here you seem to be creating and resizing thumbnails on the fly. :
if ([[NSUserDefaults standardUserDefaults] boolForKey:cellresimyuk_s])
cell.imageView.image = [[self Resim_Artwork:[aradizi objectAtIndex:indexPath.row]]
imageScaledToSize:CGSizeMake(65, 50)];
This is bound to jam up smooth tableView scolling. All of these should be pre-processed and cached, or at least only processed once here and cached for reuse.
Time-consuming nonUI processing like this can go onto another thread so that your scolling stays smooth even if the image isn't ready to show. Something like…
if ([[NSUserDefaults standardUserDefaults] boolForKey:cellresimyuk_s])
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
UIImage* image =
[[self Resim_Artwork:[aradizi objectAtIndex:indexPath.row]]
imageScaledToSize:CGSizeMake(65, 50)];
dispatch_async(dispatch_get_main_queue(), ^{
//check our cell is still valid
if ([[self.tableView cellForRowAtIndexPath:indexPath] isEqual:cell]){
cell.imageView.image = image;
}
});
});
else
cell.imageView.image = nil;
Regarding the date formatter: these are heavyweight objects, you need to ensure to only create once, keep in a property for reuse. I suggest you do the following:
Declare two date formatter properties and another for your zero'd date. Initialise them all in viewDidLoad:
- (void)viewDidLoad {
[super viewDidLoad];
self.hoursFormat = [[NSDateFormatter alloc] init];
[self.hoursFormat setDateFormat:#"HH:mm:ss"];
self.minsFormat = [[NSDateFormatter alloc]init];
[self.minsFormat setDateFormat:#"mm:ss"];
self.zeroDate = [self.hoursFormat dateFromString:#"00:00:00"];
}
Then in cellForRowAtIndexPath:
NSDate* date = [self.zeroDate dateByAddingTimeInterval:theTimeInterval];
if (theTimeInterval >= 3600) {
self.label.text = [self.hoursFormat stringFromDate:date];
} else {
self.label.text = [self.minsFormat stringFromDate:date];
}
He Was, Thank you for the answer. performance was very nice. But since I made this change, the program closes.
new codes:
NSMutableArray *aradizi;
if (tableView == self.searchDisplayController.searchResultsTableView)
aradizi = self.filteredListContent;
if (indexPath.section == 2 && tableView != self.searchDisplayController.searchResultsTableView)
aradizi = self.dizi_klasorler;
if (indexPath.section == 3)
aradizi = self.dizi_veriler;
if ([[NSUserDefaults standardUserDefaults] boolForKey:cellresimyuk_s]){
if (cell.imageView.image == nil)
cell.imageView.image = [[self Resimm:#".varsayilan" Koordinat:CGRectMake(120,1320, 80, 60) retinami:0 grubu:6] Resim_Skala:CGSizeMake(60, 45)];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
UIImage* image = [[self Resim_Artwork:[[aradizi objectAtIndex:indexPath.row] objectForKey:urlsi_s]] Resim_Skala:CGSizeMake(60, 45)];
dispatch_async(dispatch_get_main_queue(), ^{
//check our cell is still valid
if (tableView == self.searchDisplayController.searchResultsTableView){
if ([[self.searchDisplayController.searchResultsTableView cellForRowAtIndexPath:indexPath] isEqual:cell])
cell.imageView.image = image;
}else{
if ([[self.tableView cellForRowAtIndexPath:indexPath] isEqual:cell])
cell.imageView.image = image;
}
});
});
}else
cell.imageView.image = nil;
http://img29.imageshack.us/img29/1083/ekranresmi2013020301553.png
http://img502.imageshack.us/img502/5591/ekranresmi2013012919525.png
I have a number of blog apps. Recently, some of them started experiencing some issues. I use ASIHTTP Classes and GDataXML Classes to parse the xml of a wordpress feed, and put each item (article) into a mutable array. The tableview is then supposed to load all of the stories into a cell for each article. The issue I am having is that new articles are not being displayed on first run, the user is having to Pull to Refresh, and then the new article displays. I ran a test just now on an app. The article was posted a few hours ago. I ran the app, it wasn't there. Pulled to refresh, it showed. Closed down the app completely, restarted it, and it was gone again. Here is the code in the TableView's implementation:
#implementation RootViewController
- (void)refresh {
self.allEntries = [NSMutableArray array];
self.queue = [[[NSOperationQueue alloc] init] autorelease];
self.feeds = [NSArray arrayWithObjects:#"http://bubblycandacebabbles.wordpress.com/?cat=-2008&feed=rss2",
nil];
for (NSString *feed in _feeds) {
NSURL *url = [NSURL URLWithString:feed];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setDelegate:self];
[_queue addOperation:request];
}
}
- (void)viewDidLoad {
[super viewDidLoad];
[activity startAnimating];
//[self.navigationController.navigationBar setBackgroundImage:[UIImage imageNamed:#"navbarcopy.png"] forBarMetrics:UIBarMetricsDefault];
self.title = #"Blog";
CGFloat nRed=111.0/255.0;
CGFloat nBlue=209/255.0;
CGFloat nGreen=229.0/255.0;
UIColor *myColor=[[UIColor alloc]initWithRed:nRed green:nBlue blue:nGreen alpha:1];
UIBarButtonItem *font = [[UIBarButtonItem alloc] initWithTitle:#"Change Font Size" style:UIBarButtonItemStylePlain target:self action:#selector(fontsizes)];
self.navigationController.navigationItem.rightBarButtonItem = font;
self.tableView.backgroundColor = myColor;
self.refreshControl = [[UIRefreshControl alloc] init];
[self.refreshControl addTarget:self action:#selector(refreshInvoked:forState:) forControlEvents:UIControlEventValueChanged];
[self refresh];
}
-(void) refreshInvoked:(id)sender forState:(UIControlState)state {
// Refresh table here...
[_allEntries removeAllObjects];
[self.tableView reloadData];
[self refresh];
}
- (void)parseRss:(GDataXMLElement *)rootElement entries:(NSMutableArray *)entries {
NSArray *channels = [rootElement elementsForName:#"channel"];
for (GDataXMLElement *channel in channels) {
NSString *blogTitle = [channel valueForChild:#"title"];
NSArray *items = [channel elementsForName:#"item"];
for (GDataXMLElement *item in items) {
NSString *articleTitle = [item valueForChild:#"title"];
NSString *articleUrl = [item valueForChild:#"link"];
NSString *articleDateString = [item valueForChild:#"pubDate"];
NSDate *articleDate = [NSDate dateFromInternetDateTimeString:articleDateString formatHint:DateFormatHintRFC822];
NSString *articleImage = [item valueForChild:#"content:encoded"];
NSScanner *theScanner;
NSString *gt =nil;
theScanner = [NSScanner scannerWithString:articleImage];
NSString *comments = [articleUrl stringByAppendingString:#"#respond"];
NSString *commentslink = [NSString stringWithFormat: #"Leave A Comment",comments];
// find start of tag
[theScanner scanUpToString:#"alt=\"\" width=" intoString:NULL] ;
// find end of tag
[theScanner scanUpToString:#"/>" intoString:>] ;
// replace the found tag with a space
//(you can filter multi-spaces out later if you wish)
NSString *test = [articleImage stringByReplacingOccurrencesOfString:[ NSString stringWithFormat:#"%#", gt] withString:#"alt=\"\" width=\"150\" height=\"150\""];
NSString *final = [test stringByReplacingOccurrencesOfString:#"float:none;height:30px" withString:#"float:none;height:1px"];
NSDateFormatter * dateFormatter = [[[NSDateFormatter alloc] init] autorelease];
[dateFormatter setTimeStyle:NSDateFormatterShortStyle];
[dateFormatter setDateStyle:NSDateFormatterShortStyle];
NSString *dateofarticle = [dateFormatter stringFromDate:articleDate];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *smalltitle = [defaults objectForKey:#"Title"];
NSString *smallbody = [defaults objectForKey:#"Article"];
NSString *bodyoftext = [[[[[[[[[[[#"<head><body bgcolor=\"#6fd1e5\" text=\"#CC0099\"><style type='text/css'>a > img {pointer-events: none;cursor: default;max-width: 310;}</style></head><b><font size=" stringByAppendingString: smalltitle ] stringByAppendingString:#"><div align=\"left\"><FONT FACE=\"noteworthy\">" ]stringByAppendingString:articleTitle] stringByAppendingString:#"</font></b><font size=" ] stringByAppendingString:smallbody ] stringByAppendingString:#"><div align=\"left\"><FONT FACE=\"noteworthy\">"] stringByAppendingString:dateofarticle] stringByAppendingString:#"</div></p><FONT FACE=\"noteworthy\">"] stringByAppendingString:final] stringByAppendingString:commentslink]stringByAppendingString:#"</FONT>"];
RSSEntry *entry = [[[RSSEntry alloc] initWithBlogTitle:blogTitle
articleTitle:articleTitle
articleUrl:articleUrl
articleDate:articleDate
articleImage:bodyoftext] autorelease];
[entries addObject:entry];
}
}
}
- (void)parseFeed:(GDataXMLElement *)rootElement entries:(NSMutableArray *)entries {
if ([rootElement.name compare:#"rss"] == NSOrderedSame) {
[self parseRss:rootElement entries:entries];
} else if ([rootElement.name compare:#"feed"] == NSOrderedSame) {
[self parseAtom:rootElement entries:entries];
} else {
NSLog(#"Unsupported root element: %#", rootElement.name);
}
}
// Customize the number of sections in the table view.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
// Customize the number of rows in the table view.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [_allEntries count];
}
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
Cell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[Cell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
RSSEntry *entry = [_allEntries objectAtIndex:indexPath.row];
NSString *substring = #"http://bubblycandacebabbles.files.wordpress.com";
NSRange textRange = [entry.articleImage rangeOfString:substring];
if(textRange.location != NSNotFound){
NSString *thearticleImage = entry.articleImage;
NSRegularExpression *expression = [NSRegularExpression regularExpressionWithPattern:#"src=\"([^\"]+)\"" options:NSRegularExpressionCaseInsensitive error:NULL];
NSString *someString = thearticleImage;
NSString *oneurl = [someString substringWithRange:[expression rangeOfFirstMatchInString:someString options:NSMatchingCompleted range:NSMakeRange(0, [someString length])]];
NSString *finalstring = [oneurl stringByReplacingOccurrencesOfString:#"src=\"" withString:#""];
NSString *thefinalstring = [finalstring stringByReplacingOccurrencesOfString:#"\"" withString:#""];
NSDateFormatter * dateFormatter = [[[NSDateFormatter alloc] init] autorelease];
[dateFormatter setTimeZone:[NSTimeZone localTimeZone]];
[dateFormatter setTimeStyle:NSDateFormatterShortStyle];
[dateFormatter setDateStyle:NSDateFormatterShortStyle];
CGFloat nRed=204.0/255.0;
CGFloat nBlue=0/255.0;
CGFloat nGreen=153.0/255.0;
UIColor *myColortext=[[UIColor alloc]initWithRed:nRed green:nBlue blue:nGreen alpha:1];
NSString *articleDateString = [dateFormatter stringFromDate:entry.articleDate];
UIFont *cellFont = [UIFont fontWithName:#"noteworthy" size:16];
UIFont *cellFont2 = [UIFont fontWithName:#"noteworthy" size:12];
CALayer * l = [cell.imageView layer];
[l setMasksToBounds:YES];
[l setCornerRadius:11];
[l setBorderWidth:2.0];
[l setBorderColor:[[UIColor blackColor] CGColor]];
cell.textLabel.text = entry.articleTitle;
cell.textLabel.numberOfLines = 2;
cell.detailTextLabel.adjustsFontSizeToFitWidth = YES;
cell.detailTextLabel.text = [NSString stringWithFormat:#"%# - Mother May I Blog", articleDateString];
cell.textLabel.font = cellFont;
cell.detailTextLabel.font = cellFont2;
cell.textLabel.textColor = myColortext;
cell.detailTextLabel.textColor = myColortext;
[cell.imageView setImageWithURL:[NSURL URLWithString:thefinalstring] placeholderImage:[UIImage imageNamed:#"iphoneicon#2x.png"]];
}
else {
CALayer * l = [cell.imageView layer];
[l setMasksToBounds:YES];
[l setCornerRadius:11];
[l setBorderWidth:2.0];
[l setBorderColor:[[UIColor blackColor] CGColor]];
NSDateFormatter * dateFormatter = [[[NSDateFormatter alloc] init] autorelease];
[dateFormatter setTimeZone:[NSTimeZone localTimeZone]];
[dateFormatter setTimeStyle:NSDateFormatterShortStyle];
[dateFormatter setDateStyle:NSDateFormatterShortStyle];
NSString *articleDateString = [dateFormatter stringFromDate:entry.articleDate];
UIFont *cellFont = [UIFont fontWithName:#"noteworthy" size:16];
UIFont *cellFont2 = [UIFont fontWithName:#"noteworthy" size:12];
cell.imageView.image = [UIImage imageNamed:#"iphoneicon#2x.png"];
cell.textLabel.text = entry.articleTitle;
cell.textLabel.numberOfLines = 2;
cell.detailTextLabel.adjustsFontSizeToFitWidth = YES;
cell.detailTextLabel.text = [NSString stringWithFormat:#"%# - Mother May I Blog", articleDateString];
CGFloat nRed=204.0/255.0;
CGFloat nBlue=0/255.0;
CGFloat nGreen=153.0/255.0;
UIColor *myColortext=[[UIColor alloc]initWithRed:nRed green:nBlue blue:nGreen alpha:1];
cell.textLabel.font = cellFont;
cell.detailTextLabel.font = cellFont2;
cell.textLabel.textColor = myColortext;
cell.detailTextLabel.textColor = myColortext;
}
return cell;
}
You need to invoke
[self.tableView reloadData];
at some point after your data has finished loading. How exactly you do this is a bit tricky, you need some way of telling when your operation queue is empty. Alternatively, you could theoretically call it after each operation in the queue is complete, that way the table will populate one at a time. This could cause problems if the user is on a slow connection, as reloading the table can cause jumps in the user experience, and I'm not positive on the thread safety of calling reloadData from a different thread