Category: Cocoa

An In-depth Look At Manual Memory Management In Objective-C

— Category: Cocoa

It feels like fleets of new developers dash themselves upon the rocky shores of Objective-C memory management every day on StackOverflow. I can't bear to write the same answers over and over again, so this article will be my final, unabridged explanation of: retain, release, autorelease, alloc, dealloc, copy, and NSAutoreleasePool. There will be some rules to memorize, but we will also take a journey under the hood for a deeper understanding.

This article is intended for people who are new to Objective-C, or who never fully learnt how manual reference counting works. It does assume that you have some programming experience, possibly in another language. If you are a beginner programmer and Objective-C is your first language, I will try to keep the explanations clear, but it may become confusing the more in-depth we get.

We will be covering:

  • A Quick Mention Of ARC And Garbage Collection
  • Coming From C/C++
  • Coming From a Garbage Collected Language (Java, Python, C#, etc.)
  • What Is Reference Counting?
  • How Does Reference Counting Work In Objective-C?
  • NSAutoreleasePool And autorelease
  • Common Mistakes

If something is not explained, or not explained very well, post a question in the comments and I'll expand the article to cover it.

Gotchas With Grand Central Dispatch (libdispatch) And Blocks

— Category: Cocoa

GCD is a nice replacement for the old performSelectorInBackground:withObject: and performSelectorOnMainThread:withObject:waitUntilDone: methods and NSOperation. It's also a nice supplement to NSThread.

However, I think it was over-hyped a little bit by Apple when it was first released. You probably have all these random deadlocks and race conditions and stuff whenever you use multiple threads, but GCD is soooooo good that you don't have to worry about that anymore. Just use these magic blocks.

The problem is that concurrent programming is notoriously hard to get right. Maybe GCD helps to make it easier, but It doesn't solve all of your problems. In fact, GCD and blocks introduce some problems of their own. This article will focus on some of those problems.

How Cocoa Bindings Work (via KVC and KVO)

— Category: Cocoa

Cocoa bindings can be a little confusing, especially to newcomers. Once you have an understanding of the underlying concepts, bindings aren't too hard. In this article, I'm going to explain the concepts behind bindings from the ground up; first explaining Key-Value Coding (KVC), then Key-Value Observing (KVO), and finally explaining how Cocoa bindings are built on top of KVC and KVO.

Why performSelector: Is More Dangerous Than I Thought

— Category: Cocoa

I fixed a rather nasty bug today in AspectObjectiveC. One particular unit test would crash with EXC_BAD_ACCESS every time. After learning far more about registers and ABIs than I ever wanted to know (thanks, Greg Parker), it dawned on me that performSelector: was corrupting memory. It was particularly hard to track down because the crash would happen a couple of lines after the call to performSelector:, when the corrupted memory was actually accessed.

I've never had a problem with performSelector: before, but this time I was using it a little differently. The return value of the selector was an NSRect.

Now for the gory explanation.

Implementing Your Own Cocoa Bindings

— Category: Cocoa

This post is the result of investigation into a stackoverflow.com question of mine.

So, you've created a spiffy NSView of your own, and have decided to make it compatible with bindings. Great! So you go and read the documentation, and you look at mmalc's GraphicsBindings examples. You override bind:toObject:withKeyPath:options: and everything works. But wait! Why isn't the NSWindowController ever being deallocated anymore?

Now you've got a nasty retain cycle on your hands. You do a little research and discover that not only do other people have the same problem, but even Apple's bindings used to have it a few years ago. How did Apple fix the problem? With the magic, undocumented class NSAutounbinder, which nobody seems to know much about.

Other people will tell you that you don't need to override bind:toObject:withKeyPath:options: and that bindings work automatically. This is only a half truth. NSObject does provide an implementation of bind:toObject:withKeyPath:options:, but it only half works. Using the default NSObject implementation, changes in the model will update the view, but the reverse is not true. When the bound property of the view changes, nothing happens to the model.

So, what is a Cocoa developer to do? I'll explain how to implement your own bindings that work exactly like Apple's, with no retain cycles. I haven't found this solution anywhere else, so as far as I know, I'm the discoverer. I feel so special. It has been mentioned before at least once. The solution is hard to find, though.