views:

125

answers:

1

Hi all,

the following code crashes the application, and I don't know why. It crashes irregularly, that means that sometimes the imageview can be shown for example 30 times when a row is clicked, sometimes it chrashes the second time when I select a row.

FYI: the activity indicator,the action sheet and the variable imageNr are defined globally and will be initialized in the viedDidLoad method.

Thanks in advance for your advices.
Sean

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
 imageNr = indexPath.row + 1;
 activityLoadView = [[UIActivityIndicatorView alloc] initWithFrame:CGRectMake(-17.5, -11, 35, 35)];
                    activityLoadView.activityIndicatorViewStyle = UIActivityIndicatorViewStyleWhiteLarge;
                    activityLoadView.autoresizingMask = (UIViewAutoresizingFlexibleLeftMargin |
                                                        UIViewAutoresizingFlexibleRightMargin |
                                                        UIViewAutoresizingFlexibleTopMargin |
                                                        UIViewAutoresizingFlexibleBottomMargin);

 actionSheetLoadView = [[UIActionSheet alloc] initWithTitle:@""
                                                   delegate:self
                                          cancelButtonTitle:nil
                                     destructiveButtonTitle:nil
                                          otherButtonTitles:nil];
 actionSheetLoadView.actionSheetStyle = UIBarStyleBlackOpaque;

 [actionSheetLoadView setMessage:[NSString stringWithFormat:@"\n\n\n\n\n\n\n\n\n\n\n\n\nLoading image ..."]];
 [actionSheetLoadView addSubview:activityLoadView];
 [actionSheetLoadView showInView:self.view];
 [actionSheetLoadView setBounds:CGRectMake(0,0,320,720)];

 [activityLoadView performSelector:@selector(startAnimating) withObject:nil afterDelay:0.1];
 [self performSelectorInBackground:@selector(showImageView) withObject:nil];
}

- (void)showImageView
{
  [self setViewInfo];
  [self.navigationController pushViewController:imageViewController animated:YES];

  [activityLoadView performSelector:@selector(stopAnimating) withObject:nil afterDelay:0.1];
  [actionSheetLoadView dismissWithClickedButtonIndex:0 animated:YES];
  [activityLoadView release];
  [actionSheetLoadView release];
}
A: 

Among other things, you are performing user interface updates on a background thread (by running -showImageView in the background). User interface elements are not threadsafe on the iPhone OS, and must be updated on the main thread. Practically everything done in the -showImageView method needs to be done on the main thread (with the possible exception of -setViewInfo, depending on what that does).

Also, be very careful when releasing objects on a background thread, as they may be in use on the main thread (or another), and this may lead to crashes.

Brad Larson
Thanks for your answer. The problem is if I use [self performSelectorOnMainThread:@selector(showImageView) withObject:nil waitUntilDone:NO]; the action sheet won't show up while the image is loading, not before the image is completely loaded.
Sean
@Sean: What is the bottleneck in the image loading? If it's simply the loading of the image into a non-visible view, do that on a background thread, then have a callback that is performed on the main thread which adds the image view to the display and does the remainder of the UI updates.
Brad Larson
hi, the problem is not to load the image (the image and the label text for the image will be set in the method -setViewInfo), it's more to show up a action view for the time the image is loading, because sometimes it takes while. do you know what i mean?
Sean
@Sean: You should be able to kick off the action sheet like you do, then perform the image loading selector after a delay (like is done for -startAnimating). The action sheet should load and display at the end of the current pass through the run loop, then your image loading code will run on the main thread while your spinner is animating in the action sheet. When done, you can dismiss the action sheet.
Brad Larson