4. Runtime
Completely dynamic message sending.
Don't need inheritance to call a method
with different objects
True introspection. Allows to watch class
hierarchy, check if an object has a
particular invariant or implements some
method, call a method by name
5. Categories and Proxies
Allows addition of methods to another class
Even a class you don't have source for
Also allows overriding of existing methods
6. Key Value Coding/Observing
Bind string names with object invariants at
run-time
Call back when the value of some invariant
is going to be / was changed
12. Syntax
Lots of square braces. Compare:
[[[MyClass alloc] init:[foo bar]] autorelease]
MyClass.alloc.init(foo.bar).autorelease
Keyed parameters: difficult to reorder them
during refactoring
13. Lighweight
The same code has to be repeated often
Little language support for anything other
than message sending
Folks could say “because there's no magic”.
But more code means more bugs
Without Cocoa this “no magic” would be
absolutely awful
15. Allocation and Initialization
Which are two separated operations
MyClass *object = [MyClass alloc] init];
Multiple constructors work via designated
initializers without any language support
self = [super init]; //assignment to self :(
if (self)
{
//init invariants
}
return self;
17. Messaging nil
Does nothing and hides real bugs
Wouldn't be so bad if it were easy to make
messaging nil scream
Cocoa messages nil as a matter of course
18. Overriding and Overloading
Categories are broken: overriding a method
more than once leads to undefined
behavior
No method overload. Need to mangle
names manually