It has very poor support for custom value types. Objective-C structs basically can't contain object pointers, so they're limited to simple things like CGRect. They also can't contain methods, so you end up writing associated code in global functions.
Protocols are extremely limited. They're basically just collections of method declarations. There's no way to add functionality to every class which conforms to a protocol.
Objective-C is often verbose to the point of painful redundancy. Consider:
NSString *x = [NSString stringWithFormat: @"%d", number];
Versus: let x = String(format: "%d", number)
Other examples include having to write the signature of every public method twice (once in the header and once in the implementation) and the need to do an annoying `self = [super init]` dance in every initializer.There's almost no functional programming stuff available, like map and reduce. This is not strictly a language complaint, but since the standard libraries are pretty tightly woven in, I think it still counts.
Generics support is really limited. What's there was only added to interoperate better with Swift, anyway!
That's a quick overview of some of the ways Swift improves on ObjC. I'm sure there's more.
let x = "\(number)"That said, Swift feels similar while being more productive:
- Lots of nice syntactic sugar to reduce noise - Optionals (and chained calls) which do much the same - Type inference! - A REPL. Pretty amazing. - Bounds checking
lots more nice features too.
Rust, D, golang, swift all appear to share a common goal of having a mid-to-low-level imperative/OO language that has learned from C/C++/ObjC's mistakes.
Though some consider this a feature, YMMV.