Cocoa: Model, View, Chuvmey

Chuvmey is a Klingon word meaning “leftovers” – it was the only way I could think of to keep the MVC abbreviation while impressing upon you, my gentle reader, the idea that what is often considered the Controller layer actually becomes a “Stuff” layer. Before explaining this idea, I’ll point out that my thought processes were set in motion by listening to the latest Mac Developer Roundtable (iTunes link) podcast on code re-use.

My thesis is that the View layer contains Controller-ey stuff, and so does the Model layer, so the bit in between becomes full of multiple things; the traditional OpenStep-style “glue” or “shuttle” code which is what the NeXT documentation meant by Controller, dynamic aspects of the model which could be part of the Model layer, view customisation which could really be part of the View layer, and anything which either doesn’t or we don’t notice could fit elsewhere. Let me explain.

The traditional source for the MVC paradigm is Smalltalk, and indeed How to use Model-View-Controller is a somewhat legendary paper in the use of MVC in the Smalltalk environment. What we notice here is that the Controller is defined as:

The controller interprets the mouse and keyboard inputs from the user, commanding the model and/or the view to change as appropriate.

We can throw this view out straight away when talking about Cocoa, as keyboard and mouse events are handled by NSResponder, which is the superclass of NSView. That’s right, the Smalltalk Controller and View are really wrapped together in the AppKit, both being part of the View. Many NSView subclasses handle events in some reasonable manner, allowing delegates to decorate this at key points in the interaction; some of the handlers are fairly complex like NSText. Often those decorators are written as Controller code (though not always; the Core Animation -animator proxies are really controller decorators, but all of the custom animations are implemented in NSView subclasses). Then there’s the target-action mechanism for triggering events; those events typically exist in the Controller. But should they?

Going back to that Smalltalk paper, let’s look at the Model:

The model manages the behavior and data of the application domain, responds to requests for information about its state (usually from the view), and responds to instructions to change state (usually from the controller).

If the behaviour – i.e. the use cases – are implemented in the Model, well where does that leave the Controller? Incidentally, I agree with and try to use this behavior-and-data definition of the Model, unlike paradigms such as Presentation-Abstraction-Control where the Abstraction layer really only deals with entities, with the dynamic behaviour being in services encapsulated in the Control layer. All of the user interaction is in the View, and all of the user workflow is in the Model. So what’s left?

There are basically two things left for our application to do, but they’re both implementations of the same pattern – Adaptor. On the one hand, there’s preparing the Model objects to be suitable for presentation by the View. In Cocoa Bindings, Apple even use the class names – NSObjectController and so on – as a hint as to which layer this belongs in. I include in this “presentation adaptor” part of the Controller all those traditional data preparation schemes such as UITableView data sources. The other is adapting the actions etc. of the View onto the Model – i.e. isolating the Model from the AppKit, UIKit, WebObjects or whatever environment it happens to be running in. Even if you’re only writing Mac applications, that can be a useful isolation; let’s say I’m writing a Recipe application (for whatever reason – I’m not, BTW, for any managers who read this drivel). Views such as NSButton or NSTextField are suitable for any old Cocoa application, and Models such as GLRecipe are suitable for any old Recipe application. But as soon as they need to know about each other, the classes are restricted to the intersection of that set – Cocoa Recipe applications. The question of whether I write a WebObjects Recipes app in the future depends on business drivers, so I could presumably come up with some likelihood that I’m going to need to cross that bridge (actually, the bridge has been deprecated, chortle). But other environments for the Model to exist in don’t need to be new products – the unit test framework counts. And isn’t AppleScript really a View which drives the Model through some form of Adaptor? What about Automator…?

So let me finish by re-capping on what I think the Controller layer is. It’s definitely an adaptor between Views and Models. But depending on who you ask and what software you’re looking at, it could also be a decorator for some custom view behaviour, and maybe a service for managing the dynamic state of some model entities. To what extent that matters depends on whether it gets in the way of effectively writing the software you need to write.

Posted in cocoa, metadev, ooa/d, smalltalk | 4 Comments

When techs collide

If you’ve ever seen the film Ghostbusters, you’ll know that each of the proton packs was, on its own, very powerful and capable of performing its function. Combine two, by crossing the streams, and rather than something twice as powerful you have a potentially Zuul-beating, potentially universe-destroying chaotic mess on your hands.

Such a combination I found today, when I mixed a little bit of Distributed Objects with a soupçon of Cocoa Bindings to create, um, Distributed Bindings (calling it Cocoa Objects would just be rude).

It’s actually just as simple as you think it will be, so there’s no point in any sample code. You can basically use the answer to the FAQ question on DO. Once you’ve got the proxy object in the client, use it as the observable controller in -bind:toObject:withKeyPath:options:. And that’s it!

Well, not quite it. You’ll notice that things are a wee bit crashy, which is why this is somewhat like crossing the streams. Both Bindings and DO use the Proxy pattern to achieve their magic, but because the two systems have no special knowledge of each other the proxy connections are not kept in sync. If your server object mutates after the DO connection disappears, then it tries to send a KVO notification to an object that’s no longer there…boom. Having a client-server system where the client can crash the server is of, well, dubious utility. There are some things that you could do to mitigate this, for instance looking for NSConnectionDidDieNotification (in the server) or opening a heartbeat RPC for the client to “check in” with the server. These fixes will work perfectly, if the vended object is updated predictably enough that you can reliably take care of broken connections between KVO notifications. Without that you’re SoL, as the server won’t reliably get a DO exception – more often than not it’ll segfault. But while this may be unstable, it still is damned cool.

Posted in cocoa, objc | Leave a comment

A lack of CocoaHeads

Apologies to anyone sat in the Glue Pot wondering where the nerds are. Due to a general feeling of bitter colditude we’ve postponed for a couple of weeks. But never fear, Scotty shall still wax forth on SearchKit on the 16th of the month.

Posted in whatevs | Leave a comment

Most favouritest and least favourite Macs

The current meme seems to be, given the 25th anniversary of the launch of the Mac (and I’m not going to let it slip by that it’s the 20th anniversary of the NEXTSTEP 1.0 launch this year, either) to write an opinion on the best and worst Macs we’ve ever used. So here’s mine.

Obviously my Mac use comes as a result of Mac OS X, so neither of my choices are particularly old machines. My favourite is a definite thing, and it’s the first Mac I ever bought myself – a PowerMac G4 Sawtooth. I didn’t own it from new; I bought it from a contractor who was writing a WebObjects app for us when I worked at the University. It was a “G4 Server” according to the sticker, which really just meant that it came with a SCSI adaptor fitted standard, and the pièce de resistance: Mac OS X Server 1.2 installed :-). The 1.x series of MOSES (Mac OS Enterprise Server) was a release of Rhapsody, a straight port of OPENSTEP to the PowerPC with a couple of changes. Most noticable were the configuration of startup items, the platinum UI and some changes to the Workspace to make it a little more similar to the Mac OS Finder. The 450MHz G4 I had was blazingly fast in this OS, and none too shabby when it came to more modern OS X too. When I finally sold it on it was running 10.4.

My least favourite is less clear-cut, I have a choice of two. But I think I’m going to give it to the Beige G3 Power Mac I borrowed long-term, I think from the University, when I was a student. This was really a slightly updated Power Mac 8600 with a faster CPU in, but the CPU’s capabilities were significantly limited by the architecture (50MHz bus, 5MBPS SCSI) which really belonged to the older 603-alike processors. I seem to remember it having some weird amount of memory, like 208MB, because I’d scrounged different chips from different places, but even with that much RAM it couldn’t do more than crawl in OS X 10.0-10.2. As with the G4 I installed Server 1.2, but many of the Java components really were staggeringly slow on this system.

Posted in whatevs | 1 Comment

Quote of the year (so far)

From David Thornley via StackOverflow:

“Best practices” is the most impressive way to spell “mediocrity” I’ve ever seen.

I couldn’t agree more. Oh, wait, I could. thud There it goes.

Posted in Business, metadev, mythicalmanmonth, rant | 1 Comment

Tautology of the year (so far)

From iDefense, via DarkReading:

A recent wave of fatwas issued by radical Islamic religious leaders in that region authorizing these groups to use cyberattacks to defend Islam has opened the door for these groups to wage cyberattacks, according to iDefense.

In other news, water has been found to be wet. (seriously considering a “my beloved language, you’ve killed it!” tag)

Posted in rant, security | Leave a comment

Quick antispam observation

One thing I’ve been doing recently is removing my membership of a load of websites that I don’t seem to have used in a long time. One side effect of not using a website in a long time is that I forget the password I created for the account, so I get to see how the website handles failed login attempts. Often, quite a few times :-(.

Now, some of these sites – and I’ve been notifying the owners as I go – give you a different failure message if you get your password wrong or your e-mail address. This is, to quote the twitterverse, made of fail. It means these websites can be used to automatically generate lists of the members’ e-mail addresses; useful to spammers, phishers (remember that the list is based on being a member of a particular site, so it’s easy to target the phish at that site) and even for later trying to compromise accounts on that site. I’d really avoid being a member of any site whose login page worked like that, and try to get them to change their error messages.

Posted in whatevs | 2 Comments

What’s new in 2009

Of course, it’s a bit early for a retrospective of 2008, besides which I’ve already written 73 entries this year, my most prolific year to date on iamleeg. And that doesn’t count numerous tweets, stack overflow contributions and of course the occasional piece of source code here or there for some security company. As the noise of fireworks and exploding media players sounds across the world, it’s time to pre-emptively ditch 2008 and see what we can expect from 2009. Specifically, what you can expect from me.

It looks to me like the most popular pieces on this blog are the opinions and how-tos regarding Cocoa development, particularly my thoughts on properties and Cocoa memory management round-up. Don’t worry, there’s definitely more of this coming. As well as preparing for this Mac Developer Network conference talk I’ve been discussing recently, I’ve got another exciting – and unfortunately secret – project on the go now which should see plenty of collateral blog posting in the first half of the next year, all about Cocoa development. There’ll also be a bit more of an iPhone mix-in; obviously for much of last year the SDK either didn’t exist or was under non-disclosure, but now I’ve got more reasons to be using Cocoa Touch it will also be mentioned on here. I shall also be delving a bit deeper into Darwin and xnu than I have in previous times.

One example of Cocoa-related information is meetup announcements; I’m still involved in the local CocoaHeads chapter and I’ll endeavour to post an advance warning for each meeting here. I know many of my readers are in the States but a few of you are local so please do come along! In fact, if you’re not local (or “bissen’t from rond theez partz”, as we say here) then consider going to your nearest CocoaHeads or starting a new one. It’s a great way to find out who’s working on Mac or iPhone development in your area, share tips and stories and build up that professional contacts network.

Previously I’ve been concerned that readers here at iamleeg don’t seem interesting in commenting on my posts, but these days I’m no longer worried. I can tell how many people are reading, and of those how many are regulars, and I have to say that the blog is doing pretty damn well. Of course, if you do feel inclined to join in the discussion (particularly if I’ve got something wrong, or missed an important point from a post) then you should feel perfectly at liberty to leave a comment.

Finally, have a happy new year!

Posted in cocoa, darwin, iPhone, kernel, macdevnet, meta-interwebs, personal, UNIX | Leave a comment

Cocoa Memory Management

It becomes evident, thanks to the mass centralisation of the neverending september effect that is stackoverflow, that despite the large number of electrons expended on documenting the retain/release/autorelease reference counting mechanism for managing memory in Cocoa, Cocoa Touch, UIKit, AppKit, Foundation, GNUstep, Cocotron and Objective-C code, very few people are reading that. My purpose in this post is not to re-state anything which has already been said. My purpose is to aggregate information I’ve found on the topic of managing memory in Cocoa, so I can quote this post in answers to questions like these.

In fact, I’ve already answered this question myself, as How does reference counting work? As mentioned in the FAQ, I actually answered the question “how do I manage object lifecycles in (Cocoa|GNUstep|Cocotron)”? It’s actually a very violently distilled discussion, so it’s definitely worth checking out the references (sorry) below.

Apple have a very good, and complete, Memory Management Programming Guide for Cocoa. They also provide a Garbage Collection Programming Guide; remember that Objective-C garbage collection is opt-in on 10.5 and above (and unavailable on iPhone OS or earlier versions of Mac OS X). GNUsteppers reading along should remember that the garbage collector available with the GNU objc runtime is entirely unlike the collector documented in Apple’s guide. GNUstep documentation contains a similar guide to memory management, as well as going into more depth about memory allocation and zones. Apple will also tell you how objects in NIBs are managed.

The article which gave me my personal eureka moment was Hold Me, Use Me, Free Me by Don Yacktman. Stepwise has another article, very simple rules for memory management in Cocoa by mmalc, which is a good introduction though with one caveat. While the table of memory management methods at the top of the article are indeed accurate, they might give you the impression that keeping track of the retain count is what you’re supposed to be doing. It’s not :). What you’re supposed to be doing is balancing your own use of the methods for any given object, as described in rules 1 and 2 of “Retention Count rules” just below that table.

James Duncan Davidson’s book “Learning Cocoa with Objective-C” has not been updated in donkey’s years, but its section on memory management is quite good, especially the diagrams and the “rules of thumb” summary. Luckily, that section on memory management is the free sample on O’Reilly’s website.

If reading the theoretical stuff is all a bit too dry, the Mac Developer Network have a rather comprehensive memory management training video which is $9.99 for non-MDN members and free for paid-up members.

Finally, Chris Hanson has written a good article on interactions between Cocoa memory management and objc-exceptions; if you’re using exceptions this is a good discussion of the caveats you might meet.

Posted in cocoa, FAQ, gnustep, iPhone, leopard, memory, nextstep, objc, openstep | 3 Comments

Wikipedia == fail

On the same day that fark announce the wikipedia irony, I would like to point out a similar situation I saw just today.

This is from the Susie Dent entry discussion page:

IMDb relies on the contributions of the public, so isn’t an overly reliable source.

Posted in whatevs | Leave a comment