{
"$type": "site.standard.document",
"description": "This post is mostly based on a presentation I’ve done on the last CocoaHeads meeting in Kraków. (If you’re a Cocoa developer and you’re in Kraków on a 2nd Thursday of a month, come say hi!)\n\nThea idea was basically to collect all the things that have changed in ObjC in the recent years in one place. There were quite a few of these (which is a great thing!) and it’s sometimes hard to remember all of them, especially if you’re trying to update the code of an older project to newer coding style. Hopefully you will also find something here that you didn’t know about before.\nLLVM to the rescue\n\nIt used to be rather painful to write code in ObjectiveC. I mean, if you’ve been doing it for years you probably got used to it; but for people that switch from other languages, especially dynamic ones like Python or Ruby, it was a torture. Not only you have to write all those scary square brackets, manage the memory manually (which was a constant source of crashes), type those method names that don’t fit in one line, but you can’t even create an array or a hash easily? That was just madness.\n\nLuckily, a lot has changed since I started learning ObjC a few years ago, and a lot of the things I used to complain about at first are no longer true. It’s still not as pleasant as coding in Ruby (and it will never be), but it’s much less painful than it was before.\n\nMost of these changes were made possible by investing time to develop LLVM, a new compiler infrastructure that has now completely replaced GCC and allowed Apple to add features to the language much faster than before. It took a few years, it wasn’t always easy (and it’s still a minor annoyance at times), but it was definitely worth it.\n\nInstance variables for @property\n\nRequires: modern runtime\n\n(What’s a modern runtime, you might ask? Check out Apple’s docs for an explanation, but in short, OSX has had that since 10.5 (but only on 64-bit machines) and iOS has had that from the beginning.)\n\nThis one’s fairly old, but I’ve included it for completeness. Previously, if you declared a @property in a class, you also had to declare a matching ivar (instance variable), like this:\n\n@interface MyKlass {\n NSMutableArray *list;\n}\n\n@property NSMutableArray *list;\n\n@end\n\nActually, you might still need to do this if you want to support 32-bit Macs (but there aren’t a lot of these left around). This was rather annoying and repetitive, especially since you also had to declare the same variable in @synthesize and in dealloc, which means that every new variable had to be added in 4 different places manually. That’s definitely not DRY at all.\n\nIf you only support modern runtimes, you can now skip the ivars if you have a @property:\n\n@interface MyKlass\n\n@property NSMutableArray *list;\n\n@end\n\nBlocks\n\nRequires: OSX 10.6 / iOS 4.0\n\nBlocks are what you might know as closures or lambdas from other languages - anonymous functions defined inline in code, capturing the context in which they’re created. Just like in other languages, th…",
"path": "/2013/04/20/whats-new-in-objc/",
"publishedAt": "2013-04-20T12:24:00Z",
"site": "at://did:plc:oio4hkxaop4ao4wz2pp3f4cr/site.standard.publication/3mn5mackuba26",
"tags": [
"Cocoa"
],
"textContent": "This post is mostly based on a presentation I’ve done on the last CocoaHeads meeting in Kraków. (If you’re a Cocoa developer and you’re in Kraków on a 2nd Thursday of a month, come say hi!)\n\nThea idea was basically to collect all the things that have changed in ObjC in the recent years in one place. There were quite a few of these (which is a great thing!) and it’s sometimes hard to remember all of them, especially if you’re trying to update the code of an older project to newer coding style. Hopefully you will also find something here that you didn’t know about before.\nLLVM to the rescue\n\nIt used to be rather painful to write code in ObjectiveC. I mean, if you’ve been doing it for years you probably got used to it; but for people that switch from other languages, especially dynamic ones like Python or Ruby, it was a torture. Not only you have to write all those scary square brackets, manage the memory manually (which was a constant source of crashes), type those method names that don’t fit in one line, but you can’t even create an array or a hash easily? That was just madness.\n\nLuckily, a lot has changed since I started learning ObjC a few years ago, and a lot of the things I used to complain about at first are no longer true. It’s still not as pleasant as coding in Ruby (and it will never be), but it’s much less painful than it was before.\n\nMost of these changes were made possible by investing time to develop LLVM, a new compiler infrastructure that has now completely replaced GCC and allowed Apple to add features to the language much faster than before. It took a few years, it wasn’t always easy (and it’s still a minor annoyance at times), but it was definitely worth it.\n\nInstance variables for @property\n\nRequires: modern runtime\n\n(What’s a modern runtime, you might ask? Check out Apple’s docs for an explanation, but in short, OSX has had that since 10.5 (but only on 64-bit machines) and iOS has had that from the beginning.)\n\nThis one’s fairly old, but I’ve included it for completeness. Previously, if you declared a @property in a class, you also had to declare a matching ivar (instance variable), like this:\n\n@interface MyKlass {\n NSMutableArray *list;\n}\n\n@property NSMutableArray *list;\n\n@end\n\nActually, you might still need to do this if you want to support 32-bit Macs (but there aren’t a lot of these left around). This was rather annoying and repetitive, especially since you also had to declare the same variable in @synthesize and in dealloc, which means that every new variable had to be added in 4 different places manually. That’s definitely not DRY at all.\n\nIf you only support modern runtimes, you can now skip the ivars if you have a @property:\n\n@interface MyKlass\n\n@property NSMutableArray *list;\n\n@end\n\nBlocks\n\nRequires: OSX 10.6 / iOS 4.0\n\nBlocks are what you might know as closures or lambdas from other languages - anonymous functions defined inline in code, capturing the context in which they’re created. Just like in other languages, they can be used e.g. for callbacks to be called when some task is completed (very useful in network handling code), functional-style array operations (map/select/reduce) or for concurrency (NSOperation).\n\nThe syntax is kind of awkward, but it’s mostly just in the method definitions (the more arguments, the worse it gets):\n\n- (void) load: (NSString *) url callback: (void (^)(NSString *)) callback {\n NSString *response = [connector requestTo: url];\n callback(response);\n}\n\nThe method you see above accepts a callback block that takes an NSString and returns void. To simplify such declarations, you might want to use a typedef to give a name to this type of block:\n\ntypedef void (^NetworkCallback)(NSString *);\n\n- (void) load: (NSString *) url callback: (NetworkCallback) callback;\n\nHowever bad this looks in a statically-typed language, it’s still worth it because it often lets you do things that were either not possible before or required much more code to achieve the same effect. And passing blocks to a method defined somewhere else is a bit simpler:\n\n[list enumerateObjectsUsingBlock: ^(id obj, NSUInteger i, BOOL *stop) {\n NSLog(@”#%d = %@”, i, obj);\n}];\n\nenumerateObjectsUsingBlock: is a built-in method in NSArray that acts more or less like Ruby’s Array#each or JavaScript’s Array#forEach. There aren’t many other such methods in the Foundation classes, but you can easily add some yourself.\n\nPrivate variables in @implementation\n\nRequires: Xcode 4.2 + LLVM + modern runtime\n\nPrivate variables were previously declared in the interface file (*.h), like this:\n\n// MyKlass.h\n\n@interface MyKlass {\n NSMutableArray *list;\n}\n\n@end\n\nIt’s not a big problem really, but the interface file is meant for the users of your class, and ivars are usually only used internally. It makes much more sense then to put them in the implementation file (*.m).\n\nSince Xcode 4 (with LLVM) we were able to put the ivars in a class extension in the *.m file:\n\n// MyKlass.m\n\n@interface MyKlass () {\n NSMutableArray *list;\n}\n\n@end\n\n@implementation MyKlass\n// ...\n@end\n\nI never liked class extensions though, they somehow make the implementation file more messy by adding a second top-level block. Fortunately, we don’t really need them anymore since now we can just put the ivars in the @implementation block:\n\n// MyKlass.m\n\n@implementation MyKlass {\n NSMutableArray *list;\n}\n\n// ...\n\n@end\n\nAutomatic Reference Counting (ARC)\n\nRequires: Xcode 4.2 + OSX 10.6 64-bit / iOS 4.0\n\nThis was a huge change. Since version 10.5 OSX has had a garbage collector, but on iOS you had to manage the memory manually, which was a major pain in the ass (even though it got better if you remembered all the rules and used the Xcode analyzer to detect bugs). We were waiting for the day when iOS finally gets a GC too, but instead we got something better.\n\nWhat is ARC? It’s a compiler feature that basically inserts all the memory management method calls in the right places for you automatically. From the developer’s perspective it’s very similar to a GC, but it usually works slightly faster since there’s no overhead to run the GC in the background when memory runs out. There’s just one requirement - you have to follow all the rules Xcode requires from you, so that it knows what it’s supposed to do for you.\n\nThanks to ARC, a method that used to look like this:\n\n- (NSArray *) views {\n NSMutableArray *arr = [[NSMutableArray alloc] init];\n UIView *view = [[UIView alloc] initWithFrame: frame];\n [arr addObject: view];\n\n [view release];\n return [arr autorelease];\n}\n\nNow looks like this:\n\n- (NSArray *) views {\n NSMutableArray *arr = [[NSMutableArray alloc] init];\n UIView *view = [[UIView alloc] initWithFrame: frame];\n [arr addObject: view];\n\n return arr;\n}\n\nThere’s no need to call retain, release or autorelease (in fact you’re not allowed to call them yourself). This also greatly simplifies dealloc methods - now most of the time you don’t need them at all (unless you have some custom code there apart from release and [super dealloc] calls).\n\nA funny twist in the story is that GC is deprecated on OSX 10.8 - so clearly ARC is the way forward on all Apple platforms.\n\nYou can read everything about converting your code to ARC in Apple’s documentation.\n\nForward method declarations\n\nRequires: Xcode 4.3\n\nEveryone that starts coding in ObjC encounters this error sooner or later:\n\n@implementation MyKlass\n\n- (void) bar {\n [self foo]; // <-- Xcode: WTF is this?\n}\n\n- (void) foo {\n // ...\n}\n\nOk, it’s not exactly what Xcode says, but you get the idea: inside your methods you can only call methods of the same class that are either defined earlier in the file, or at least declared in an interface. So you either add a declaration to the class extension (which I hate), or to the public interface (which is kind of wrong), or you start moving methods around, messing up your original order, hoping that it’s enough for Xcode to shut up (which is even more stupid).\n\nSince Xcode 4.3 this is fortunately a thing of the past. You can now order your private methods as you like.\n\nAutomatic @synthesize\n\nRequires: Xcode 4.4 + modern runtime\n\nRemember how I wrote that you had to add every new variable in 4 places? Now it’s finally down to 1, because you don’t even have to declare @synthesize for properties.\n\nSo if you have an interface like this:\n\n@interface MyKlass\n\n@property NSString *name;\n\n@end\n\nYour implementation can now look like this, and the name property will be synthesized automatically:\n\n@implementation MyKlass\n\n- (void) printName {\n NSLog(@”%@ %@”, _name, self.name);\n}\n\n@end\n\nNotice how the ivar’s name starts with an underscore (if you want a different name, you still need to use @synthesize). For me this seems like a slight hint that you should rather access it through the property whenever possible, even inside the class (that’s just my personal interpretation though).\n\nObjC literals\n\nRequires: Xcode 4.4\n\nI’ve been waiting for this since I wrote my first line of ObjC, and I’m pretty sure I wasn’t alone at this. We can now finally create NSArrays, NSDictionarys and NSNumbers like in any other language, without having to call methods with very long names or resorting to C macros and other magic.\n\nTo wrap numbers or booleans in NSNumber (e.g. to insert them into an array), you had to call one of these:\n\n[NSNumber numberWithBool: YES]\n[NSNumber numberWithInt: 1]\n[NSNumber numberWithFloat: x]\n\nTo create an array, you had to call this method (and remember to add a nil at the end!):\n\n[NSArray arrayWithObjects: @”twitter”, @”facebook”, @”github”, nil]\n\nCreating a dictionary was even worse, because the order of key-value pairs was also inverted. And if you wanted to include numbers or booleans in the dictionary, it was getting really complex:\n\n[NSDictionary dictionaryWithObjectsAndKeys:\n @”Kuba”, @”firstName”,\n @”Suder”, @”lastName”,\n [NSNumber numberWithInt: 30], @”age”,\n nil]\n\nNow you can use @[] to create arrays, @{} to create dictionaries and prepend @ to numbers to turn them into NSNumbers:\n\n@1, @2.5, @YES, @(x)\n\n@[@”twitter”, @”facebook”, @”github”]\n\n@{ @”firstName”: @”Kuba”, @”lastName”: @”Suder”, @”age”: @30 }\n\nLooks much better, doesn’t it? :)\n\nArray & dictionary subscripting\n\nRequires: Xcode 4.4 + OSX 10.6 64-bit / iOS 5\n\nAnother extension to NSArray and NSDictionary syntax is that you can also look up and insert objects into them using a familiar syntax known from other languages instead of having to call getter and setter methods explicitly.\n\nInstead of:\n\n[array objectAtIndex: 2]\n[array replaceObjectAtIndex: 0 withObject: @”first”]\n\nYou can now do:\n\narray[2]\narray[0] = @”first”\n\nAnd the same thing for dictionaries - before:\n\n[dictionary objectForKey: @”id”]\n[dictionary setObject: @”jsuder” forKey: @”author”]\n\nAfter:\n\ndictionary[@”id”]\ndictionary[@”author”] = @”jsuder”\n\nBehind the scenes the compiler still calls appropriate methods to find or insert elements. What’s more, if you implement these methods in your own classes - even ones completely unrelated to NSArray and NSDictionary - you can make them act like arrays and dictionaries and use the same syntax on them. Note that these aren’t exactly the same methods you used to use with NSArray and NSDictionary, they’re new methods that were added specially for this purpose.\n\nFor example, if you have a list-like object, you can access it like an array if you define objectAtIndexedSubscript::\n\n- (id) objectAtIndexedSubscript: (NSUInteger) i {\n return list[i];\n}\n\nNSLog(@”record = %@”, collection[5]);\n\nAnd if you have an object that can look up some internal elements using a key, you can make it work like a dictionary:\n\n- (id) objectAtKeyedSubscript: (id) key {\n for (Node *node in tree) {\n if ([node.name isEqual: key]) {\n return node;\n }\n }\n\n return nil;\n}\n\nNSLog(@”node = %@”, xmlDocument[@”date”]);\n\nYou can find a more complete documentation about literals and subscripting on the LLVM site.\n\nThere’s also a trick you can use to make subscripting work on iOS 4.3 (normally it doesn’t work, because the new lookup/insertion methods weren’t originally present in NSArray in NSDictionary) - more info here.\n\nExtras from Foundation\n\nFinally, I wanted to include some additions to the Foundation framework that aren’t technically syntax extensions, but are still useful things that you might have missed.\n\nJSON parsing\n\nRequires: OSX 10.7 / iOS 5.0\n\nIf you wanted to parse JSON data in earlier versions of iOS/OSX, you had to use one of the open source libraries available, like TouchJSON, YAJL, JSONKit etc. (see my benchmark comparing their performance). Apple now includes an NSJSONSerialization class in the SDK that handles JSON parsing and serialization, so you don’t need any third party libraries for that:\n\n[NSJSONSerialization JSONObjectWithData: data\n options: 0\n error: &err];\n\nRegular Expressions\n\n Requires: OSX 10.7 / iOS 4.0\n\nJust like with JSON parsing, if you needed to use regular expressions, you probably had to include RegexKit or RegexKitLite in your project. Now there’s a built-in NSRegularExpression class in Foundation that you can use for this purpose (though it has less features and a less friendly syntax):\n\nNSRegularExpression *re =\n [NSRegularExpression regularExpressionWithPattern: @”^\\\\w+@\\\\w+(\\\\.\\\\w+)+$”\n options: 0\n error: &err];\n\n[re matchesInString: email options: 0 range: NSMakeRange(0, 20)];\n\nThat’s about it. If I got anything wrong, please let me know. As for the iOS/OSX version requirements, they might not always be 100% correct - I’ve based them on Apple’s documentation, this ObjC Availability Index page and comments from StackOverflow, and there was sometimes conflicting information about this in different places, so if you’re not sure, you should just try for yourself what works and what doesn’t.",
"title": "What's new in ObjectiveC",
"updatedAt": "2025-06-30T01:49:16Z"
}