Add support for @defer Objective-C compiler directive

Originator:steipete
Number:rdar://32485852 Date Originated:31-May-2017 04:17 PM
Status:Open Resolved:
Product:Developer Tools Product Version:Xcode 8.3.2
Classification:Feature (New) Reproducible:Always
 
Summary:
Swift has [`defer`](https://andybargh.com/swift-defer-statement/) to schedule blocks of work to clean up when you leave the current scope. This is great for cleanup when you can exit/throw in multiple places and both simplifies code and helps to reduce leaks. See https://pspdfkit.com/blog/2017/even-swiftier-objective-c/

Steps to Reproduce:
Try to use @defer.

Expected Results:
Block in @defer should be called when the scope exits

Actual Results:
Compiler error. Feature isn’t there ;)

Version:
Xcode 8.3.2

Notes:
CGImageSourceRef imageSource = CGImageSourceCreateWithURL((CFURLRef)fileURL, NULL);
if (!imageSource) {
    return NO;
}
 
CGImageRef image = CGImageSourceCreateThumbnailAtIndex(imageSource, 0, NULL);
if (!image) {
    return NO;
}
 
thumbnail = [UIImage imageWithCGImage:image scale:scale orientation:UIImageOrientationUp];
CFRelease(imageSource);
CFRelease(image);
return YES;
 
Notice the leak? If creating the image fails, we leak imageSource as we exit early. Of course that’s fixable we special-handle the first exit condition, but that’s hard and easy to get wrong. Better: Use defer to declare what needs to happen when things go out of scope.

CGImageSourceRef imageSource = CGImageSourceCreateWithURL((CFURLRef)fileURL, NULL);
if (!imageSource) {
    return NO;
}
pspdf_defer { CFRelease(imageSource); }

But I don’t think I need to convince anyone how useful defer is, as it’s part of Swift.
See https://pspdfkit.com/blog/2017/even-swiftier-objective-c/

Comments

We use a macro for now. Not even C++ needed:

https://gist.github.com/steipete/624b4dbafc79d13ac8dade04f5eec407

Read more at https://pspdfkit.com/blog/2017/even-swiftier-objective-c (WIP, goes public mid July, get a preview if you read radars and let us know what we can add. :)


Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!