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
FileManagerclass with class methods for creating, writing to, and closing files.In the
mainfunction, we use a try-finally block to ensure that the file is closed after we’re done with it, similar to howdeferworks in the original example.The
@finallyblock 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
@finallyblock to avoid potential issues.Error handling is done through Objective-C’s exception mechanism. If an error occurs during file operations, an
NSExceptionwill be thrown.
To run the program:
$ clang -framework Foundation defer.m -o defer
$ ./defer
creating
writing
closingThis 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.