Perché non respinge non è stato immediatamente su IOS5, licenziando il licenziamento UiIMagePickerController?

StackOverflow https://stackoverflow.com/questions/8409461

Domanda

Ho un UableViewController che fa apparire un UiImagePickerController, l'utente fa una foto, colpisce il pulsante d'uso, Picker si licenzia per mostrare un filatore di miniatura personalizzato mentre l'immagine viene elaborata, quindi il filatore viene sostituito dall'attuale miniatura alla fine dell'elaborazione.

Almeno è così che ha funzionato in iOS4. Ora con iOS5 si trova lì elabora fino a quando non è finito, e poi tutto funziona correttamente. Ma voglio quello spinner lì dentro in modo che l'utente sappia che sta succedendo qualcosa, altrimenti sembra che sia appeso.

Quindi ho questo:

- (void) actionSheet: (UIActionSheet *)actionSheet didDismissWithButtonIndex (NSInteger)buttonIndex {
    UIImagePickerController *picker = [[UIImagePickerController alloc] init];
    picker.delegate = self;
    picker.allowsEditing = NO;
    // yada, yada, yada
    [self presentModalViewController:picker animated:YES];
    [picker release];
}

E poi questo viene chiamato quando l'utente sceglie "usa":

- (void) imagePickerController: (UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
    [self dismissModalViewControllerAnimated:YES];
    [self performSelectorOnMainThread:@selector(processImage:) withObject:info waitUntilDone:NO];
    animate = true;
}

E poi questo viene chiamato per eseguire l'elaborazione mentre la miniatura gira:

- (void) processImage:(NSDictionary *)info
{
    UIImage *image = nil;
    NSString* mediaType = [info objectForKey:UIImagePickerControllerMediaType];
    // processing of image
    animate = false;
    [activityImageView stopAnimating];
    [activityImageView release];
    [self.tableView reloadData];
}

Come ho detto, ha funzionato perfettamente con iOS4, ma con iOS5, nessuna fortuna. Allora qual è il problema? Alla fine il raccoglitore di immagini viene licenziato, quindi perché non viene licenziato immediatamente?

È stato utile?

Soluzione

Non sono sicuro del perché ci sia una disparità tra iOS4 & iOS5 Su questo punto. Ma la tua descrizione dell'interfaccia utente è abbastanza coerente con il codice che hai mostrato. Il selettore di esecuzione sul thread principale sta facendo proprio questo, eseguendo il selettore sul thread principale, che è il thread da cui chiami. A causa di questa impostazione waitUntilDone: a NO non ha senso dal momento che non viene inviato a un altro thread è semplicemente in esecuzione in ordine. Probabilmente otterresti i risultati che desideri scambiare l'ordine, così:

[self dismissModalViewControllerAnimated:YES];
animate = true;
[self performSelectorOnMainThread:@selector(processImage:) withObject:info waitUntilDone:NO];

Ma si prega di notare che questo sarebbe rischioso nella migliore delle ipotesi, dal momento che suppongo // processing of image Non contiene concorrenza. Preferisco i blocchi per la concorrenza. E per di più mi piacciono i blocchi nidificati per rendere la concorrenza facile da seguire, ad esempio:

-(void)doSomeStuffInBackground{
    // Prepare for background stuff
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        // Do background stuff
        dispatch_async(dispatch_get_main_queue(), ^{
            // Update UI from results of background stuff
        });
    });
}

Quindi, con questo in mente, suggerirei qualcosa di più come questo:

-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{
    [self dismissModalViewControllerAnimated:YES];
    [self processImage:info];
}

-(void)processImage:(NSDictionary *)info{
    animate = true;
    UIImage *image = nil;
    NSString* mediaType = [info objectForKey:UIImagePickerControllerMediaType];

    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        // processing of image here on background thread

        dispatch_async(dispatch_get_main_queue(), ^{
            // update UI here on main thread
            animate = false;
            [activityImageView stopAnimating];
            [activityImageView release];
            [self.tableView reloadData];
        });
    });
}

Ciò scaricherebbe il lavoro principale in un thread di sfondo per far rimanere reattivo l'interfaccia utente.

Altri suggerimenti

Prova ad usare

[[picker presentingViewController] dismissViewControllerAnimated:YES completion:nil]; 

invece di:

[[picker parentViewController] dismissModalViewControllerAnimated: YES];
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top