3 votes

Fuite du NSFileCoordinator

Il s'agit d'une question triviale de gestion de la mémoire liée aux blocs et je ne suis pas sûr de savoir quand/où fc devrait être libéré

NSFileCoordinator *fc = [[NSFileCoordinator alloc] initWithFilePresenter:nil];
NSError *error = nil;
[fc coordinateWritingItemAtURL:sourceURL
                       options:NSFileCoordinatorWritingForDeleting
                         error:&error
                    byAccessor:^(NSURL *newURL) {

            // if error is not nil this block will not be called
            NSError *anError = nil;
            NSFileManager *fm = [NSFileManager defaultManager];
            [fm removeItemAtURL:newURL error:&anError];
            dispatch_async(q_main, ^{
                // change to the main queue and update the UI
                completion(anError);
        });
        // *** (1) Release here ? ***
        // [fc release];
        }];

// *** (2) or Release here ? ***
// [fc release]

if (error) {
    // change to the main queue and update the UI
    dispatch_async(q_main, ^{
        completion(error);
    });
}

Je pense que libérer à (1) serait OK (pas de fuites) mais est-ce vraiment la façon standard de faire les choses ? (libérer un objet dans le bloc que le même objet appelle ??). Je ressens une certaine bizarrerie ici.

Au point (2), c'est également OK, mais seulement parce que le bloc accesseur est appelé de manière synchrone.

À des fins d'apprentissage... et si le bloc accesseur s'appelait de manière asynchrone ? (Un cas imaginaire qui n'est pas nécessaire pour le NSFileCoordinator). fc un ivar ou est-il possible de le faire en première approche ?

Toute aide est appréciée

)

2voto

sbooth Points 9275

Pour le code donné, je libérerais à (2). Si vous libérez à (1) vous pouvez démolir fc par en dessous de lui-même. Il n'y a aucun moyen de savoir ce que fc pourrait avoir besoin de faire après avoir invoqué le bloc.

Pour le cas asynchrone, j'ai utilisé un code comme celui-ci (bien que pas avec NSFileCoordinator ):

__block NSWindowController *wc = [[NSWindowController alloc] initWithWindowNibName:@"foo"];
[NSApp beginSheet:[wc window] modalForWindow:[self window] completionHandler:^(NSInteger returnCode) {
    if(NSOKButton == returnCode) {
      // Do something
    }
    [wc release], wc = nil;
  }];

-beginSheet:modalForWindow:completionHandler: est une catégorie que j'ai ajoutée à NSApplication .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X