5 ms·
A Year’s Worth of Opinions about Objective-C
- joshuaellinger 13y agoAs a C# dev without a real project for the iPhone, I couldn't get past how cluttered the same code looked. It would be nice to hear how the class library compared to VCL.
- Strilanc 13y agoAssuming you mean the BCL (base class library). In my experience, the BCL is more comprehensive. For example, the iOS framework lacks a built-in queue or a sorted list (as far as I know). One thing Obj-C does have, that I miss in C#, is equality methods defined for collections. You can compare the contents of arrays and sets and dictionaries without writing any special code or using special methods. (Although you can break it by creating cyclical structures, since it does naive recursion instead of unification.)
- jrmg 13y agothe iOS framework lacks a built-in queue The convention for this sort of thing is to use an NSArray, inserting at position 0 to enqueue and removing the last object to dequeue. The NSArray class is actually written in a way that makes this efficient (for some great analysis see http://ridiculousfish.com/blog/posts/array.html http://ridiculousfish.com/blog/posts/array.html). or a sorted list (as far as I know) For sorted lists, I think you're right, you'd have to do it yourself. The question a Cocoa old-hand might ask would be if you _really_ need it to be always-sorted, or if you can keep your objects in an array, dictionary or set and sort them before using or iterating - or maybe just iterate the collection in a specific order instead of sorting it at all. If you do need to keep it sorted all the time, note that _inserting_ into an NSArray is also more efficient than you might assume. Keeping a sorted NSArray up to date yourself might not be expensive (it would be a bit more complicated than an auto-sorting class though, of course).
- jawngee 13y agoYou have to sort it yourself, but it's super easy. For NSArray's: NSArray * sortedArray=[array sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) { // your code here }]; For NSMutableArray's: [marray sortUsingComparator:^NSComparisonResult(id obj1, id obj2) { // your code here }];
- drewcrawford 13y agoIn defense of ObjC's type system (which is the author's major gripe). It is a duck-typed language. This is the philosophy that "if it walks like a duck... it's a duck." This is the philosophy used by lots of modern languages like Python, Ruby, and JS. Meanwhile there is the statically-typed system, which wants you to declare things to be ducks explicitly (or to pick up a duck declaration through an inheritance system). This is the philosophy used by Java, C++, etc. Anyway, the author's gripe isn't with ObjC's types. The author's gripe is with any duck-typed system. The whole point of these type systems is to avoid providing any strong guarantees about types. If you want strong typing, use a strongly-typed language. C++ may align better with this author's programming ideology. It's also worth pointing out that runtime type checks are, all else being equal, slow. ObjC is used primarily in mobile environments where speed is a concern. As the author discovered, you can opt in to type checking by using NSAssert. This forces you to think about whether the cost of a dynamic type check is acceptable. NSAsserts are also disabled by default in release builds, so this gives you checking when you need them (development) and speed when you don't (production). C++'s type system is deliberately constructed in such a way that the compiler can do the bulk of the type enforcement, which is much faster than runtime type checking. Alternately stated, this means that the programmer must write code in such a way that the compiler can infer/enforce type checks, or else they will get type errors. The author's complaints about not enough compiler errors seem to suggest to me that he would be more at home in a language like C++ that is specifically designed for this purpose.
- Strilanc 13y ago(Author here) I definitely prefer static typing over dynamic typing. I don't really mind duck typing so much as I mind dynamic duck typing (for example I like how Go does duck typing). I do try to mention that preference for static typing in the post a few times, to make it clearer that it's the dynamism that's bothering me (as opposed to the design being wrong).
- frou_dh 13y ago"static duck typing" AKA structural typing ;-) Discussions about typing seem pretty fruitless because there are often a lot of people talking past each other because they're not working off of shared definitions of what the terms (typed untyped static dynamic strong weak) actually mean.
- berzniz 13y agoI actually like the way nil is treated. I'm not a big fan of writing code with guards all the time like this: // As in C#/Java if (obj != null) { obj.doSomething(); } At least in javascript it's easier with the && operator: str && str.doSomething(); In Obj-C you can just: [str doSomething]; // If you really care if it happened or not, then introduce a check for nil Once you get used to the idea that nil doesn't break your code, you start writing your methods accordingly. For me, a lot of the stuff you write about (ARC, Blocks, literals) are the great improvements to the language. Before ARC you had C/C++ like control of the memory and you could do some crazy stuff like an object holding on to itself and then committing suicide (pretty useful actually). With ARC you only have to care about retain cycles and declaring weak/strong pointers. It's an awesome feature for a non-GC environment. Blocks are truly the biggest change in Obj-C and made the code much easier to develop. Any async task is now easy to deal with. Alongside GCD, multi-threading is made simple. What I'm really trying to say is that from the first iPhone OS to iOS7, we've seen some major improvements to the language. If it continues at the same pace, you'll might like it more in your next year's review.
- rbritton 13y agoThere are some annoying circumstances where you still have to check for nil, so it's not exactly consistent. For example: 1. Adding nil to an array triggers an exception. 2. Trying to set a dictionary key/value pair with nil for either value triggers and exception. It'd be more consistent with other parts of the code base if setting a nil value unset that particular key. 3. Calling a block storage variable that's nil will crash. It'd be nice if these all were no-ops too.
- jawngee 13y agoIt is consistent though. Sending a message to nothing gets your nothing. Adding nothing to something that expects something causes an exception.
- rbritton 13y agoI suppose it depends on what you consider consistent (i.e., all nil operations should be no-ops or just message-sending operations), but that only covers 1 and 2. Trying to invoke a nil block still crashes.
- norswap 13y agoI'm considering writing a similar post. For me the biggest write was how steep the learning curve for the whole Cocoa (referring mostly to UIKit, but also to a few other pieces) shebang was. It's not even that the system is badly designed (arguably it could be a lot better though) but that the documentation is so so bad. API docs are okay, but don't give you the big picture. Their reference guide, on the other hand are so abstract and 1000-mile high that you don't really get practical value out of them. After that, the system with small inconsistencies, imprecise documentation and undocumented behaviour. In short, it's not very "systematic". You don't feel there's a well thought-out system that will allow you to predict what will happen. This is especially true when talking about layout, but also other things such how views / controllers interact. There's not a culture of "best practices", so interfacing with someone else's UI libraries can be hell. @Author: Any thoughts about this?
- Strilanc 13y agoI haven't done enough UIKit stuff to really comment on it, other than to say I also still find a lot of the conventions confusing or at least weird and also find that the documentation fails to answer my questions. I also don't get the distinction between a UIView and a UIControllerView. In C# land I always associated view=.xaml and controller=.cs. In obj-c land both views and view controllers have a .xib and .m/.h, so it's not clear to me how responsibilities are divided.
- mmorey 13y agoA view can be a scene in a storyboard file, a xib file, or you can create your views programmatically (.m and .h). A view controller is always a .m and .h. And if you're not following the MVC pattern you can put your view code in your view controller's loadView/viewDidLoad method.
- Strilanc 13y agoThanks, that's actually a helpful thing to mention and obvious in hindsight. A view controller can be the owner of a .nib but not the class of a .nib, so the .nib is never a view controller. Are there particular divisions of responsibility that come up w.r.t. what you put in a view's .m/.h vs what you put in the controller's .m/.h? Is the .m/.h of a view considered to be a controller in the MVC sense but not in the UIViewController sense?
- aaronbrethorst 13y agoI don't intend to belittle the author's writeup of their experience with Objective-C. I've been working with the language off and on for over ten years, now, and have been working almost exclusively in it professionally for the last 3 or 4, and I have a ton of complaints about it. But... With one exception, I feel like this entire post could be summed up as 'I don't like dynamic languages, static typing FTW!' The one exception is with regard to merging pbxproj files, which, I agree, is a fantastically awful experience. The only worse experience I have ever had working with this stack is in trying to merge XIBs (short answer: just don't even bother trying).
- mikeash 13y agoGetting off topic, but have you seen the new xib format in Xcode 5? It's totally different and way better. I haven't actually tried merging one yet, but I'm highly optimistic for when it comes up.
- aaronbrethorst 13y agoNo, I haven't. I'm guessing you have to either explicitly upgrade your existing XIBs to it, or recreate them? Thanks for the head's up, I'll check it out. Also, thanks again for the ridiculously awesome blog. It's been one of my favorite reads for years. edit: OK, I had a chance to check out the file format. This looks far more sane and human-readable than it has in the past. Related: I will happily pay $100 to anyone for a piece of software that has an auto layout constraint generator that works with XIB files and doesn't suck.
- mikeash 13y agoI think you have to manually convert existing ones. I'm fuzzy on the exact details, but I think there's a popup in the right-side info pane that lets you choose which Xcode version (and thus which format) you want to use for the xib. Glad you like the blog!
- Strilanc 13y agoThe type system is definitely where I feel the most friction. However, I think a summary of "dynamic bleh" omits the bits of praise and discussion that I consider important to the content. I'm also not sure if nil-vs-null counts as dynamic-vs-static.
- lupinglade 13y agoSo Objective C is not what you're used to? Awh... It's no secret that Objective C software is generally richer and more robust, thanks exactly to its "strange" differences. Sure it takes effort to learn a new way of doing things but if you're willing, you'll soon realize it was worth it. Dynamic and compiled is a great combination.