Manual memory management is bad but you can't escape it in C so `goto` is mildly useful there for that purpose. In all other languages you get better ergonomics.
* In Rust you wouldn't need any of that boilerplate because lifetime is automatically managed (& Rust has Objc bindings).
* If you turn on ARC & use the NS types you don't need this (they map to the same thing with no overhead for these primitives, so there's no good reason not to do this unless you are just being masochistic).
* In ObjC++ you should still use ARC. But if you felt masochistic, you could do:
auto string0 = unique_ptr(CFCreateString("Hello"));
auto string1 = unique_ptr(CFCreateString("World"));
auto arrayObj = unique_ptr(CFCreateMutableArray(kCFAllocatorDefault, 2, kCFTypeArrayCallBacks, kCFTypeDictionaryKeyCallBacks, ));
auto thing = unique_ptr(CFCreateMutableDictionary(kCFAllocatorDefault, 1, kCFTypeDictionaryKeyCallBacks, kCFTypeDictionaryValueCallBacks));
if (!arrayObj || !string0 || !string1 || !thing) {
return nil;
}
if (!CFArrayAppendValue(arrayObj.get(), string0.get()) || !CFArrayAppendValue(arrayObj.get(), string1.get())) {
return nil;
}
if (!CFDictionaryInsertObjectWithKey(thing.get(), arrayObj.get(), "somekey")) {
return nil;
}
return thing.release()
In C++ you could also use scope guards if you didn't like the `unique_ptr` stuff (not part of the stdlib yet, but it's not hard to roll your own).
The point I'm trying to make is that there are much cleaner ways of obtaining that result in whatever language you choose. If you do that, maybe you too won't be responsible for a goto fail security flaw [1].
EDIT: BTW. This advise isn't out of the blue. This was 100% a strong culture even within Apple 5 years ago. If you're concerned about performance of ARC, consider that Apple dogfoods it internally for nearly every part of the OS. The only pieces it's not used are for large historical codebases where the migration cost is a factor. Performance of ARC vs manual just isn't something anyone looks at. For the historical codebases usually one would use the ObjC++ approach instead.
[1] https://nakedsecurity.sophos.com/2014/02/24/anatomy-of-a-got...