

First Glance at Objective-C and the iPhone SDK (by a Java and C Developer) - webb
http://webbtech.posterous.com/a-java-developers-first-glance-at-objective-c

======
jimbokun
"Message (function call) syntax seemed funky."

"When I first realized the language offered weak typing -- with the (id)
variable -- it seemed to go against everything that C stood for in my mind."

These are good observations, and reflect deliberate choices in the design of
Objective C.

The funky message syntax makes clear that a sending a message is _not_
equivalent to calling a function. Conflating the two will eventually lead to
pain and confusion.

Declaring a variable as "id" does indeed launch you out of C's type system,
into a realm where any object can potentially respond to any message,
regardless of its type. This leads to a lot of interesting possibilities and
patterns that Cocoa (and iOS) leverage heavily.

~~~
othermaciej
Sending a message is indeed equivalent to calling a function, specifically the
function objc_msgSend (or one of its variants, depending on return type).

It's also very much like calling a virtual function in C++, only slower.

~~~
js2
In the normal case it's still very fast
[http://www.friday.com/bbum/2009/12/18/objc_msgsend-tour-
part...](http://www.friday.com/bbum/2009/12/18/objc_msgsend-tour-part-3-the-
fast-path/)

~~~
othermaciej
My day job is working on a mixed C++/Objective-C project (Safari). My
statement that ObjC method calls are slow is based on staring at a lot of
profiles and poking into the assembly. If you study the page you linked, you
can see that even the fast path results in four serialized load instructions:

1) Load class pointer from object movq (%rdi),%r11

2) Load cache pointer from class movq 0x10(%r11),%r8

3) Load cache entry (IMP) from cache movq 0x10(%r8,%rcx),%r11

4) Load function pointer from IMP movq 0x10(%r11),%r11

Notice that each of these loads reads into a register which is then treated as
an address by the next load. This does a great job of totally stalling your
pipeline while you wait for memory reads. I've been staring at this same grim
pattern in the profiler since the days of PowerPC.

C++ virtual function calls are doubly-indirect in the worst case (read vtable
pointer from object, read function pointer from vtable). And because it's
emitted at the call site and not hidden in a function, the compiler can often
reduce it down to singly indirect or even direct link it as a static call, if
it can prove the exact type.

Objective-C is not as bad as some say, but if your code is highly optimized,
method call overhead can become a bottleneck.

~~~
js2
Nice reply, thank you.

------
spearo77
While that's a decent summary of his current perspective, I'd wager that the
biggest adjustment won't be memory management. Although that is a trap for new
players, a bigger adjustment will be to think and code in the "Cocoa-way".

In my experience, Cocoa Touch has all the benefits of it's very mature Mac OS
foundation, and to develop effectively, and minimise friction, you need adhere
to the Cocoa way.

~~~
sigzero
I thought ObjC had garbage collection now?

~~~
webb
I don't know the history here, but based on the autopool directives it looks
like they toyed with the idea.

~~~
donmcc
With gc enabled, [autoreleasePool drain] asks the gc to run (IIRC), with gc
disabled, it releases everything currently owned by the pool. Even on the Mac,
you may still want to build your app without gc for performance reasons, and
Apple gives you that option.

I'm sure we'll see gc on iOS devices eventually, but it's probably too memory
hungry to be practical on the phone right now.

~~~
rst
Either that, or the objC gc isn't ready for a phone-constrained environment
yet. Android seems to manage OK, but they put in a lot more up-front work into
making it viable there.

------
shadowmatter
I started about a month ago... As someone with a background in
Java/C++/Python, here are some more that have caught my attention:

\- The ability to assign types as ClassName<Protocol>, instead of the protocol
specifying the type completely. Neat, I guess...

\- Because it's message passing, you get duck typing for free, albeit with
compiler warnings (you send a message, and wouldn't you know it, the selector
exists!). Not that I recommend this approach over protocols.

\- The awesomeness of @selector, especially if you're coming from Java and
used to writing anonymous classes everywhere simply for the sake of making
functions first-class entities.

\- The lack of public/protected/private visibility modifiers and how variables
are suddenly part of the public API when you define them in properties. Say
you have a variable you want to keep private, but you need to frequently
update its value. You go ahead and define @property (nonatomic, retain) for it
so within the class so that you can simply do self.varName = newVarValue to
update it. But now all your clients/outside clients will see; you need to
write the release-and-retain setter yourself in the .m file to prevent this.

\- The minimalism of Xcode. Hey, it's faster than Eclipse, thank $DEITY for
that. But when I want to alphabetize the filenames in the left sidebar, I have
to go to Edit -> Sort -> By Name for _every_ file group?

~~~
rbritton
You can use @public, @private, or @protected on the instance variables.
Unfortunately these do not extend to the properties themselves and you have to
use a different approach as in the sibling comment:

    
    
      @interface SomeClass (SomePrivateCategory)
         @property (nonatomic, assign) NSUInteger count;
         ...
      @end

~~~
chc
Actually, Objective-C has class extensions for just this purpose. No need for
a private category.

------
ianl
One of the biggest pitfall for beginners is the fact you can send messages to
nil objects.

Secondly, while this is minor, I find it annoying that when declaring array's
I have to include nil at the end.

------
ary
Exactly when and where did Apple suggest not to use NSAutoReleasePool?

~~~
webb
I know this is a broad statement on my part. Apples says the following in the
hello world tutorial, "In general, however, you should try to avoid using
autorelease wherever possible since it means memory may be reclaimed later
than it would be if you used release."

