Defer in Objective-C
In Objective-C, there isn’t a direct equivalent to the defer
keyword. However, we can achieve similar functionality using the @finally
block in a try-catch-finally statement. Here’s how we can implement the same concept:
#import <Foundation/Foundation.h>
@interface FileManager : NSObject
+ (NSFileHandle *)createFile:(NSString *)path;
+ (void)writeToFile:(NSFileHandle *)file;
+ (void)closeFile:(NSFileHandle *)file;
@end
@implementation FileManager
+ (NSFileHandle *)createFile:(NSString *)path {
NSLog(@"creating");
return [NSFileHandle fileHandleForWritingAtPath:path];
}
+ (void)writeToFile:(NSFileHandle *)file {
NSLog(@"writing");
[file writeData:[@"data\n" dataUsingEncoding:NSUTF8StringEncoding]];
}
+ (void)closeFile:(NSFileHandle *)file {
NSLog(@"closing");
[file closeFile];
}
@end
int main(int argc, const char * argv[]) {
@autoreleasepool {
NSFileHandle *file = nil;
@try {
file = [FileManager createFile:@"/tmp/defer.txt"];
[FileManager writeToFile:file];
}
@finally {
if (file) {
[FileManager closeFile:file];
}
}
}
return 0;
}
In this Objective-C version:
We define a
FileManager
class with class methods for creating, writing to, and closing files.In the
main
function, we use a try-finally block to ensure that the file is closed after we’re done with it, similar to howdefer
works in the original example.The
@finally
block will always execute, regardless of whether an exception is thrown or not, ensuring that our cleanup code (closing the file) always runs.We check if the file is non-nil before closing it in the
@finally
block to avoid potential issues.Error handling is done through Objective-C’s exception mechanism. If an error occurs during file operations, an
NSException
will be thrown.
To run the program:
$ clang -framework Foundation defer.m -o defer
$ ./defer
creating
writing
closing
This approach ensures that the file is closed after being written, mimicking the behavior of the defer
keyword in the original example.
It’s important to note that while this achieves a similar result, the @finally
block in Objective-C is not exactly the same as defer
. The @finally
block is tied to a specific scope and exception handling, whereas defer
in Go is more flexible and can be used outside of exception handling contexts.