This is one trivial question of memory management related with blocks and I am not sure when/where fc
should be released
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);
});
}
I think releasing at (1) would be OK (no leaks) but is this really the standard way of doing things? (releasing an object in the block that the same object calls??). I feel some weirdness here.
At (2), Is also OK but only because the accessor block is called synchronously.
For learning purposes... what if that the accessor block would be called asynchronously? (An imaginary case not necessary of NSFileCoordinator) In such a case would I need to make fc
an ivar or is it just fine to do as the first approach?
Any help is appreciated
:)
For the given code, I would release at (2). If you release at (1) you could tear down
fc
from underneath itself. There is no way to know whatfc
might need do after invoking the block.For the asynchronous case, I've used code like this (although not with
NSFileCoordinator
):-beginSheet:modalForWindow:completionHandler:
is a category I've added toNSApplication
.