It’s safer, less code and more flexible.

Old Code:

- (void)setSelectedUnit:(FZUnit *)unit {
  if (selectedUnit == unit) {
    return;
  }
 
  RELEASE(selectedUnit);
  selectedUnit = [unit retain];
  [self updateButtonArea:unit];  
}

New:

// add notification when selected unit changes
__block __typeof__(self) blockSelf;
 = self;[self addObserverForKeyPath:@"selectedUnit" task:^(id obj, NSDictionary *change) {
[blockSelf updateButtonArea:blockSelf.selectedUnit];
}];

Isn’t this code much more elegant? And you don’t have to fuzzle around with memory retains – and other classes can use the property for kvo too (which we disabled with the old variant above)

Note two specialities. We use “blockSelf” to work around the retainment cycle when using self inside a block. Second, KVO is normally not block-based. I’m using a KVO Trampoline that makes KVOs much more powerful and flexible. Big thanks to Apple Employee Andy Matuschak for NSObject+BlockObservation!

Just found that on Twitter – and since it’s just THAT awesome to know how to fix “Cancelling call as the malloc lock is held so it isn’t safe to call the runtime” or “warning: Not safe to look up objc runtime data”. – i’ll reblog it. Thanks to Fat Cat Software.

First, I need to find out which thread is the one holding the malloc lock. The easiest way to do this is to type “info threads” in the GDB console. That will list all the threads running in your application, along with the topmost function call on the stack for each thread. Now, the exact function that’s responsible can be a number of different things, including malloc obviously, but also any number of Cocoa, CoreFoundation, Core Graphics, or any number of other allocation related routines. So, you’ll have to do a little judging to figure out exactly which thread is the culprit in your particular case.
Switch to that thread to make it the current thread. You can do this either by typing “thread” followed by the thread number in the console, or by just selecting the appropriate thread from the pop-up menu in Xcode’s debugger window.
Once you’ve done that, go and type “set scheduler-locking on” in the console.
Then, just click the “Step Out” button in Xcode to make the current thread finish whatever allocation function it was in. It’s possible you’ll need to step out two or more levels in order to make sure you’re out of malloc-land. The trick here is that, since you enabled the scheduler-locking flag, only the thread that you selected will be run. This means that the thread your breakpoint is in (as well as all the other threads in your program) will not have budged at all, and once you’re out of the allocation routine, you can then switch back to that thread and print things out!
Finally, after you’ve finished your debugging, make sure to go back and do a “set scheduler-locking off” before continuing with the rest of your program. Leaving it on could cause other problems such as deadlocks in further debugging, so you should only leave it on as long as necessary to get the job done.

For our one year cocoaheads meeting at vienna’s metalab i gave two lightning taks about some new awesome frameworks I use: Hockey for AdHoc updating and Lumberjack for better logging.

If you are an iOS or Mac developer around vienna, feel free to come at our next metting! (checkout cocoaheads.at for dates)

Here are the slides if you’re curious (Hockey / CocoaLumberJack)

I guess until now nearly EVERY block i wrote created a retain cycle. Bummer. But if you think about it, it’s obvious. Most calls in a block use self. This gets retained, and your retain cycle is perfect.

But at least for blocks, the solution is quite simple:

 __block __typeof__(self) blockSelf = self;
        _observerObj = [[NSNotificationCenter defaultCenter] addObserverForName: ... queue: [NSOperationQueue mainQueue] usingBlock: ^(NSNotification *note) {
            [blockSelf doSomethingWith: note];
        }];

Note: this is needed, because blocks normally live on the stack, but addObserverForName will copy our Block up to the heap, thus keeping it and creating a retain cycle – as every variable within the block gets retained. It’s not needed to do _blockSelf if you execute a block that does not get copied.

Variables that are declared with __block won’t be retained. But it’s easy to forget… and even using a instance variable will retain self, because all calls translate from variable to self->variable.

So take care on your blocks!

Want awesomely fast and flexible logging in your iOS/Cocoa apps? Don’t use NSLog! Use cocoalumberjack.

I’ve written an custom formatter to make it even more awesome. It will give you output like this:

2010-09-09 15:38:58:125(207) [AppDelegate application:didFinishLaunchingWithOptions:/59] app is starting up...

Look again. You get:

  • Log Level (Info is omitted, can be Verbose, Warn, Error)
  • Exact Timestamp
  • Thread ID
  • Class
  • Function Name
  • Line Number (wooot!)
  • Message

Have fun!

top

Switch to our mobile site