开发者

long delay when calling cocoa method

开发者 https://www.devze.com 2023-03-06 13:54 出处:网络
I have a method for saving the contents of a UIScrollView with a user-supplied filename. Everything works fine, except that there is a long delay when the user taps the \"Save\" button and the method

I have a method for saving the contents of a UIScrollView with a user-supplied filename.

Everything works fine, except that there is a long delay when the user taps the "Save" button and the method is called. I can't work out what's calling the delay, nor find a way to indicate to the user that everything is ok, we have not crashed!

I thought the delay was occurring during the renderInContext, but it seems to be happening a lot earlier, when there is not much else going on.

Here is the troublesome method:

- (void)captureViewImage {

    NSLog(@"captureViewImage called!");

// long delay happens here!

    fileNamer.title = @"Preparing to save...";

    // get user's file name
    NSString *fileName = fileNamer.fileNameField.text;

    // dismiss keyboard
    [fileNamer.fileNameField resignFirstResponder];

    // dismiss modal view
    [self dismissFileNamingFormSheet];

    CGRect oldFrame = mainScrollView.frame;

    // capture off-screen content
    mainScrollView.frame = CGRectMake(0, 0, 1024, 1432);

    // make screenshot
    UIGraphicsBeginImageContext(mainScrollView.bounds.size);
    [mainScrollView.layer renderInContext:UIGraphicsGetCurrentContext()];
    UIImage *screenImg = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    // save screenshot in docs dir
    NSData *pngData = UIImagePNGRepresentation(screenImg);
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDir = [paths objectAtIndex:0];
    [pngData writeToFile:[documentsDir stringByAppendingPathComponent:fileName] 
                 options:NSDataWritingAtomic error:nil];

    // revert scroll view
    mainScrollView.frame = oldFrame;

}

fileNamer is a custom class that throws up a UIModalPresentationFormSheet asking the user to supply a name for the file. It looks like this:

@implementation FileNamingViewController

@synthesize fileNameField, newFileName;


- (id)initWithNibName:(NSString *)nibNameOrNil 
               bundle:(NSBundle *)nibBundleOrNil parent:(TestDriveViewController *) myParent {

    if (self == [super initWithNibName:@"FileNamingViewController" bundle:nil]) {
        UIBarButtonItem *rightButton = [[UIBarButtonItem alloc] 
                                        initWithTitle:@"Save" 
                                        style:UIBarButtonItemStyleDone 
                                        target:myParent 
                                        action:@selector(captureViewImage)];
        self.navigationItem.rightBarButtonItem = rightButton;
        [rightButton release];

        UIBarButtonItem *leftButton = [[UIBarButtonItem alloc] 
                                        initWithTitle:@"Cancel" 
                                        style:UIBarButtonItemStyleBordered 
                                        target:myParent 
                                        action:@selector(dismissFileNamingFormSheet)];
        self.navigationItem.leftBarButtonItem = leftButton;
        [leftButton release];

        self.title = @"Save As?";
    }
    return self;
}


// UITextFieldDelegate

- (void)textFieldDidEndEditing:(UITextField *)textField {
    [fileNameField resignFirstResponder];
}


- (void)viewDidLoad {
    [fileNameField becomeFirstResponder];
    [super viewDidLoad];
}

fileNamer is initialized and released as follows:

- (void)presentFileNamingFormSheet {
    fileNamer = [[Fil开发者_JAVA技巧eNamingViewController alloc] 
                 initWithNibName:nil 
                 bundle:nil 
                 parent:self];

    fileNamingNavCtrl = [[UINavigationController alloc]
                        initWithRootViewController:fileNamer];

    fileNamingNavCtrl.modalPresentationStyle = UIModalPresentationFormSheet;

    [self presentModalViewController:fileNamingNavCtrl
                            animated:YES];

    // resize modal form sheet
    fileNamingNavCtrl.view.superview.frame = CGRectMake(0, 0, 540, 115);

    // reposition modal form sheet
    CGPoint position = CGPointMake(self.view.center.x, self.view.center.y - 50);
    fileNamingNavCtrl.view.superview.center = position;
}

- (void)dismissFileNamingFormSheet {
    [fileNamer release];
    [fileNamingNavCtrl release];
    [self dismissModalViewControllerAnimated:YES];  
}

Output from Time Profiler:

Running (Self)      Symbol Name
1109.0ms   37.0%    argb32_image_mark_rgb32
328.0ms   10.9%     blkclr
171.0ms    5.7%     lo_alltraps
134.0ms    4.4%     pmap_enter
116.0ms    3.8%     png_write_find_filter
102.0ms    3.4%     pmap_remove_range
55.0ms    1.8%      pmap_get_mapwindow
47.0ms    1.5%      vm_page_lookup
47.0ms    1.5%      ml_set_interrupts_enabled
43.0ms    1.4%      vm_page_grab
38.0ms    1.2%      OSAddAtomic64
34.0ms    1.1%      hw_lock_to
31.0ms    1.0%      alphaProviderGetBytes
30.0ms    1.0%      hw_lock_unlock
26.0ms    0.8%      png_read_filter_row
25.0ms    0.8%      deflateInit_
23.0ms    0.7%      vm_map_lookup_entry
23.0ms    0.7%      adler32
22.0ms    0.7%      memory_object_recover_named


I found out what was causing this. The image I was saving contained a lot of transparent views. For example, I had a lot of UIButtons which had an alpha value of 0.05 to make them more or less disappear. I didn't realise I could just set the button type to custom to make it invisible (I created the view along time ago). Once I set everything in my image view to have an alpha value of 1.0, the saving process became a lot quicker.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号