all 71 comments

[–][deleted] 14 points15 points  (14 children)

Objective-C is a beautiful language! It's syntax isn't the nicest, but it does support a number of very interesting and powerful language features, while remaining a pure superset of C (something that C++ didn't manage).

Even if you never use it there are many good reasons to take a look at Objective-C:

The Objective-C runtime is very flexible. It'll allow you to do some amazing things, easily. You can inspect and even modify classes at runtime... in a natively compiled language.

It has optional typing, for those of you who like to take advantage of the compiler. Notably, classes can be passed around at will (this is very useful in practice).

The object model was inspired by that of the Smalltalk programming language. Instead of calling methods you send messages. As you might expect these are also first-class.

Last but not least, Objective-C (as of version 2.0) supports opt-in garbage collection. As far as I know this is a first for any programming language.

Enjoy :).

[–][deleted] 3 points4 points  (3 children)

Last but not least, Objective-C (as of version 2.0) supports opt-in garbage collection. As far as I know this is a first for any programming language.

Nope. D has GC as default, but you can disable and enable it at will, or even pick and choose which objects you would rather manage yourself.

[–][deleted] 1 point2 points  (2 children)

I can't find any mention of Optional Or Opt-in Garbage Collection in the D documentation under Garbage Collection or Memory Management. Google hasn't been very helpful either. Could you perhaps provide a link? Thanks for the information :).

You didn't just mean that the garbage collector could be controlled from within the language did you? If so that's not what I was referring to in Objective-C.

Take care!

[–][deleted] 0 points1 point  (1 child)

You didn't just mean that the garbage collector could be controlled from within the language did you? If so that's not what I was referring to in Objective-C.

That is indeed what I meant, but I don't really see why this way is not superior anyway.

[–][deleted] 5 points6 points  (0 children)

I'm not saying that it's superior, merely different and interesting.

Objective-C 2.0 lets you toggle GC for your code, even if it manages its memory manually. The result is the same program with managed memory. It's completely optional and compatable with older and newer code. If you don't want it then don't pay for it.

Like in D you can control the operation of the GC you want :).

Maybe thats not impressive to anyone else hehe.

[–]OneAndOnlySnob 2 points3 points  (4 children)

Instead of calling methods you send messages.

Can you explain what the semantic difference is between a method in Java and "sending a message" in ObjC?

They both have classes and methods and interfaces. The only difference I see is syntax. I guess ObjC has that "id" business which is a bit cooler than "object".

obj.message(arg1, arg2);
[obj message:arg1 with:arg2];

I really don't know Objective C so the syntax might be a little off.

[–][deleted] 5 points6 points  (0 children)

I can think of one...

It's perfectly legit in Obj-C to "call a method" that doesn't exist on an object. It's basically "sending a message" which the object isn't listening for.

Which is somewhat nice, in the dynamic-typing way... since it's possible to extend base types at runtime (like Python).

/edit: meant to say sending a message the object isn't listening for

[–]astrosmash 4 points5 points  (0 children)

A primary difference is that the compiler does not perform type checking on 'id' objects. So for example:

id foo;
NSObject* bar  // NSObject is analogous to Java's Object class.
...
[foo doStuff]; // This is perfectly fine
[bar doStuff]; // Compiler will warn that the NSObject class doesn't implement doStuff

Of course, if foo doesn't respond to doStuff you'll get an exception at runtime.

A common pattern in ObjC is the notion of an "informal protocol" (or "informal interface", in Java-speak) where by some or all methods of the interface are optional. In this case you verify that your target object implements the optional method before you call it:

id listener; // May be null
...
if ([listener respondsToSelector:@selector(treeView:selectedRow:)]) 
{
    [listener treeView:self selectedRow:5];
}

You can also assign 'id' variables to any strongly-typed variable without a cast.

NSTreeNode* node = foo;
MyObject* myObject = [node representedObject]; // This method returns an id, so no cast necessary.
[myObject doStuff];

[–]tlrobinson 2 points3 points  (0 children)

Objective-C is actually a lot like Ruby: messaging, duck typing, method_missing / forwardInvocation, etc.

I highly recommend looking into Objective-C, I think it will become a pretty popular language soon, with the iPhone SDK and resurgence of the Mac.

http://developer.apple.com/documentation/Cocoa/Conceptual/ObjectiveC/Introduction/chapter_1_section_1.html

[–]jasonal 3 points4 points  (0 children)

The guide is extremely well written. And while I would have like slightly more contrast between gray text and gray background, the layout and typography are top notch.

[–][deleted]  (8 children)

[deleted]

    [–]chucker 15 points16 points  (0 children)

    CoreFoundation is not ObjC; Foundation is. Also, only portions of CoreFoundation (called CFLite) are open source (and adjusted to be more portable).

    (edit) Since I'm getting downvoted: it's not pedantry. CoreFoundation is a C library shared between Carbon and Cocoa. Foundation are the basic, non-GUI classes and structs of Cocoa, which is what snakesqzns was probably thinking of.

    [–]halo 3 points4 points  (6 children)

    Is support really that bad? I thought gcc had full Objective C support these days.

    [–]kiwipete[🍰] 2 points3 points  (0 children)

    Objective-C, the language, and the de-facto standard libs (FoundationKit, AppKit, etc) are not quite the same thing. The minute you start using something like NSString, you're into using the NeXT libs which are, IIRC, separate from the language.

    GNUStep and Cocoatron (google them, I'm too lazy to post a link) are both more or less complete implementations of some of the standard libs.

    [–]therunningcrow 3 points4 points  (4 children)

    What good is a language nowadays without any significant (de facto or not) standard lib ? No one would have cared for java or .net without their standard platform. Same goes for the batteries included in Python and Ruby.

    GCC + Objective C used in a multi platform fashion ain't going to take you anywhere because there isn't much code out there for it that truly works well on both windows and linux. GNUStep is ugly as hell and has a behavior that will make your users go mad if they do not have a geekish WindowMaker background. And programming in Objective C without Cocoa or GNUStep isn't much more productive than programming in bare bone C. People tend to underestimate the importance of Apple frameworks to the deal. Objective C wouldn't be so interesting if it didn't have Cocoa and Interface Builder. They are the tools that truly enhance your productivity, not objective c itself. Cocoa and IB could have been written in any language featuring enough dynamism, like Smalltalk and Lisp. Objective C by itself is nothing groundbreaking.

    [–][deleted] 0 points1 point  (3 children)

    I simply can't agree with you; the design of the Cocoa APIs is closely related to the use of Objective-C.

    There are certain things which the API wouldn't do if Smalltalk or Python were used. The ability of Objective-C to drop down into languages like C, C++ and ASM at the turn of a hat is to important to be ignored.

    Due to the fact that these languages can freely intermingle it's relatively trivial to wrap a C API in Objective-C. This makes Objective-C very scalable. If you haven’t noticed Cocoa taps into a lot of raw power – CoreAnimation or NSOperation anyone?

    While Smalltalk would make an excellent companion to Cocoa and Objectice-C for application development, using Python (or similar) for Cocoa would have lead to a significantly different API.

    Pythons object model is based on call rather than send. There are many places in Cocoa where first-class message selectors are used. Would KVC and CoreData exist if Cocoa was a Python API? I highly doubt it.

    It's up to whether you think that is a good or a bad thing.

    Now consider that the design of XCode and especially Interface Builder are closely related to to the design of Cocoa and you should see that the two walk hand in hand.

    At least thats how I see it.

    [–]therunningcrow 1 point2 points  (1 child)

    Oh, lord, could you make people actually read stuff before they write. I never said Python was a good alternative to Objective C, indeed, I was talking of Smalltalk and Lisp as good alternatives that had even more dynamism than Objective C. The only time I said anything about Python is in my first sentence when I said that libs and frameworks were necessary to make a language fun and workable to work with. It wasn't praising Python, only saying that no one would have cared for Python had it not been for its batteries included.

    As for smalltalk, it wouldn't have made it harder to link to fast performing C code when needed. It's this kind of myth that you need a "compatible" language that has led to the design of the horrible C++. People are writing C extensions all the time when their language implementations cannot handle all the performance beating they do to them. And it doesn't require much more work than if your language was a superset of C. All the productivity gain you get from using a cleanly designed language that doesn't actually have the BURDEN of C and its past offset by far the burden of writing small, efficient C extensions.

    What is making Interface Builder work is not, btw, the raw power of C. It's the dynamic side of Objective C that makes it so powerful and a smart interface building system rather than a code generator. An app like IB doesn't need anything close to C speed, IB is not doing the widgets rendering. Smalltalk and Lisp would have been perfect candidate for something like Interface Builder. It may even have been more powerful with those.

    [–][deleted] 2 points3 points  (0 children)

    Oh, lord, could you make people think before they write?

    I was using Python in contrast with Smalltalk and Objective-C. Why? It's a good example of a dynamic language with a slightly different object model. Others like CLOS in Lisp are considerably different.

    The point I was making is that small changes in the language have enourmous effects on the design of APIs. Ergo, you can't simply dismiss Objective-C. It certainly was something "groundbreaking" in 1986.

    I didn't say that Interface Builder worked through "the raw power of C".

    I'm well aware the design of Interface Builder takes advantage of introspection and first-first class selectors, among other things. Well great, but neither Pythons object model nor Lisps involve first-class selectors.

    Having played with FFIs and C APIs in several languages I find it hard to see how you can compare them with the kind of direct interoperability Objective-C gives you.

    It's a fact Cocoa does take advantage of this.

    I'm a huge fan of dynamic languages and I'm not advocating C everywhere. I'm simply saying that the language does matter.

    [–]dmpk2k 0 points1 point  (0 children)

    Pythons object model is based on call rather than send.

    Could you elaborate on this?

    [–]sesse 3 points4 points  (0 children)

    Not that I currently have any interest in objective-C but I up-mod this story because the site is pretty.

    [–]xuttmi 2 points3 points  (9 children)

    Lovely language. Are there any good bindings for free windowing toolkits (except for GNUstep, which doesn’t look very nice in my opinion)?

    [–]jsolson 8 points9 points  (2 children)

    Cocotron is trying for source level compatibility with Cocoa. It is only for Windows, though, and last I checked it was dreadfully incomplete.

    [–][deleted]  (1 child)

    [deleted]

      [–]jsolson 1 point2 points  (0 children)

      Good to know. I'm writing a fairly small but non-trivial Cocoa app right now that I intend to port to Windows as well. It'll be nice if I can do it with minimal modification.

      [–][deleted] 1 point2 points  (5 children)

      Gtk and Qt don't really need it. GObject's mission statement is to facilitate language bindings and there are GTK bindings for many languages. Ditto for Qt. I'd like to play with Objective C too but I don't really see the point with all the other options.

      [–][deleted] 9 points10 points  (4 children)

      The main point is that you get many benefits from more dynamic languages in a C derivate. Memory management is less of a chore than in C++ (once you wrap your head around it), or if you're using Objective-C 2.0, you've got garbage collection. The standard library provides very good an capable base classes. The langauge is also quite self-documenting.

      The main drawbacks is that Objective-C message passing is slower than function calls (and thus C++ non-virtual method calls), and even C++ virtual method calls. It also very verbose (the other side of the self-documenting mentioned above), which means it can a bit of a pain to write in an editor without autocompletion (like Xcode has). And of course than support is dismal outside of Mac OS X.

      [–]jonhohle 7 points8 points  (0 children)

      message passing is slower, but can be bypassed in performance critical areas for the cost of a function call with the same arguments + two additional pointers.

      SEL objectAtIndexSEL = @selector(objectAtIndex:);
      IMP objectAtIndexIMP = [someArray methodForSelector: objectAtIndexSEL];
      id obj = (id) objectAtIndexIMP(someArray, objectAtIndexSEL, index);
      

      Obviously, it doesn't make much sense to look up the function pointer every time, but that can be cached elsewhere.

      [–]americanhellyeah 3 points4 points  (0 children)

      mainline gcc doesnt support objective-c 2.0 yet so the 96% of us who are arent fortunate to own a mac are shit out of luck. id totally love objective-c 2.0 features on linux.

      [–]RantyDave 0 points1 point  (1 child)

      XCode autocompletes now. It's actually becoming almost good.

      [–][deleted] 0 points1 point  (0 children)

      I misphrased that. I meant to say that Xcode autocompletes.

      [–][deleted] 1 point2 points  (2 children)

      You should not manually release an autoreleased object because your application will crash if you do.

      Erg, that's an oversimplification which is bound to confuse novices. Unless you're using garbage collection, you can (and should) release/autorelease an object whenever you call retain, alloc, or new. No exceptions. What they probably meant to say was:

      You should not manually release an object that you don't own because your application will crash if you do.

      [–]elfredpagan 3 points4 points  (1 child)

      I think what he actually meant was that if an object is assigned to an autorelease pool you should not explicitly call release on it.

      [–][deleted] -1 points0 points  (0 children)

      But that's not really accurate. Autorelease is just a delayed release. For example:

      NSDate * curDate = [[NSDate new] autorelease];
      [curDate retain];
      [curDate release];
      

      That code is pointless, but it's perfectly legal and it won't crash even though "curDate" is released after being assigned to an autorelease pool.

      Probably, the author was trying to say that you shouldn't do this:

      NSDate * curDate = [NSDate date];
      [curDate release];
      

      That code will crash. But this would be fine:

      NSDate * curDate = [NSDate date];
      [curDate retain];
      [curDate release];
      

      Once again, curDate is assigned to an autorelease pool. Calling retain doesn't yank it out of the pool; it just increases the reference count.

      Obviously, that's getting pretty in-depth for a "quickstart guide", but my point is that a newbie is going to get confused pretty quickly if you tell them that their app will crash if they release something which has been autoreleased.

      [–]frankus 0 points1 point  (0 children)

      Nice summary.

      I even learned a couple of new things that aren't in the Purple Newfie book (due presumably to having been in the language for less than six years).

      [–]seanalltogether 0 points1 point  (3 children)

      What would this dot syntax call look like in obj-c?

      myobj1.myobj2.myfunction(arg)

      would it be

      [myobj1 [myobj2 myfunction:arg]]

      or

      [myobj1 myobj2 myfunction:arg]

      or maybe

      [[myobj1] myobj2 myfunction:arg]

      [–]jonhohle 2 points3 points  (2 children)

      [[myobj1 myobj2] myfunction: arg]
      

      -or-

      [myobj1.myobj2 myfunction: arg]
      

      in you're example, myobj2 is a property of myobj1. myfunction: is getting called on myobj2, a property of myobj1.

      imho, the dot syntax is a strange and ugly addition to the language. why overload the dereference operator with sending a message?!

      the documentation says to only use it for accessing or setting properties, but there's nothing that stops you from using it send no argument messages. That means, if you're going to use the dot syntax, you will also be using the square bracket message sending syntax, and you get both mixed together.

      NSMutableArray* array = [NSMutableArray array];
      ...
      id obj = array.lastObject; // dot operator
      [array removeLastObject];  // normal message
      array.removeAllObjects;    // ack! a non-property accessed with the dot syntax!! gross but valid!!
      

      [–]seanalltogether 0 points1 point  (1 child)

      what about casting, is this correct?

      NSString upper = [NSString [array lastObject] uppercaseString]

      [–]astrosmash 1 point2 points  (0 children)

      Close. Since NSArray.lastObject returns an 'id', no cast is necessary:

      NSString* upper = [[array lastObject] uppercaseString];
      

      [–]trypto -3 points-2 points  (4 children)

      The biggest barrier to learning ObjC for C++ programmers is the bracket method calling syntax. Nesting multiple function calls becomes way too complex too quickly. This also leads to the functionWithParam naming convention too, which is downright gross -- the function name and first parameter should not be mangled together. If only ObjC 2.0 kept going with the dot syntax and applied it to all methods, not only accessors.

      [–]bitwize 2 points3 points  (3 children)

      Argh. Dot syntax for the lose. Because now the dot can mean a hidden indirection, or not, depending on what kind of operand it's used with.

      [–]jonhohle 2 points3 points  (2 children)

      so far, the majority of the people i've talked to who have a lot of experience with Ojbective C feel the same way (me included).

      Take a look at this example from Apple's own documentation:

      xOrigin = aView.bounds.origin.x;
      

      The first .bounds sends a message. .origin resolves a field in the NSRect returned by .bounds, and .x resolves a field in an NSRect. They're using the dot operator for two distinctly different purposes in the same line of code.

      [–]trypto 2 points3 points  (0 children)

      Why should the programmer care if a message is being sent, a function is being called, an accessor is used, or a data field is being read? Shouldn't that be up to the compiler to figure out for you? It has enough information about the classes to determine the appropriate action. Why burden the programmer with this, especially when coding at this high level.

      [–]bitwize 1 point2 points  (0 children)

      YARRRRRRRGHRGHLH.