Live data from Hacker News

NSNotificationCenter with blocks considered harmful

sealedabstract.com

11–20 of 39 posts

Re: NSNotificationCenter with blocks considered harmful

#11

There's nothing really magical about this – don't cause retain cycles, everyone knows __block semantics changed with ARC, keep the returned value from the block-based NSNotificationCenter method, etc. Standard stuff. The only thing that surprised me was the reference cycle in NSAssert. Then again, given Apple's poor regard for TDD, that shouldn't surprise me.

[deleted]

Re: NSNotificationCenter with blocks considered harmful

#12

There's nothing really magical about this – don't cause retain cycles, everyone knows __block semantics changed with ARC, keep the returned value from the block-based NSNotificationCenter method, etc. Standard stuff. The only thing that surprised me was the reference cycle in NSAssert. Then again, given Apple's poor regard for TDD, that shouldn't surprise me.

Pretty much my take on it as well. Nothing out of the ordinary here except the NSAssert, but I got that before the summer.

A hack to get around the self inside the macro https://github.com/seivan/SHAlertViewBlocks/blob/develop/Exa...

Re: NSNotificationCenter with blocks considered harmful

#13

There's nothing really magical about this – don't cause retain cycles, everyone knows __block semantics changed with ARC, keep the returned value from the block-based NSNotificationCenter method, etc. Standard stuff. The only thing that surprised me was the reference cycle in NSAssert. Then again, given Apple's poor regard for TDD, that shouldn't surprise me.

I'd recommend looking at @weakify and @strongify that come with libextobjc (https://github.com/jspahrsummers/libextobjc/). Handy little helpers to avoid retain cycles with all kind of blocks.

Re: NSNotificationCenter with blocks considered harmful

#14
I consider the whole of Objective-C harmful.

It lives only in the 'platform' layer of my code. Grudgingly because Apple enforce it.

It could be worse... they could have pulled a Google and used Java - then held back the tools they develop e.g. the Java VM because they are 'dangerous' and suggest that using native code is 'bad' if it is just for performance or cross-platform reasons.

At least the interoperability with sane programming languages in Objective-C is excellent.

I'd point out the vast majority of memory management issues I have is when using someone's refcounting or gc scheme. new and delete are exactly what i want all of the time. i like to tell the machine what to do and i have developed non-trivial software without leaks /before testing for leaks/ because once you have some practice with new and delete it becomes easy and you will never look back...

As a mechanism for broadcasting information throughout an app NSNotificationCenter is slower, more complicated and (apparently) more dangerous than my hand rolled code. That should be shocking and its counter to the common idea that 3rd party and especially OS libraries should be better... there are a number of cases where they measurably aren't.

(The overhead of the objective C message mechanism - or even the RTTI mechanism which is a small part of that, exceeds that of adding or reading something from a well implemented threadsafe data structure (which is the first step to either of these things in most cases))

Re: NSNotificationCenter with blocks considered harmful

#15

There's nothing really magical about this – don't cause retain cycles, everyone knows __block semantics changed with ARC, keep the returned value from the block-based NSNotificationCenter method, etc. Standard stuff. The only thing that surprised me was the reference cycle in NSAssert. Then again, given Apple's poor regard for TDD, that shouldn't surprise me.

> everyone knows __block semantics changed

Everyone except the authors of the "Blocks Programming Topics" and the authors of the AVCamCaptureManager sample code. Maybe.

FYI the reason I included the digression about the __block change specifically is that I was recently fixing bugs on a project that uses AVCamCaptureManager, and Apple's mis-use of __block in that class, this is not a joke, through a series of corner cases, caused the status bar to unexpectedly and nondeterminisitically change color about 5% of the time on an unrelated screen.

Saying "everybody should already know how to do weak references" is great in theory. But if you are fielding weird reports for unreproducible status bar issues and it occurs to you at any time in the first hour that maybe Jim from the next cubicle used buggy sample code for a video recording feature on another screen you are a WAY better software developer than I am.

Of course this is standard stuff. But unlike a lot of standard stuff, this one can go undetected for long periods, and crop up in very unexpected places. That's the problem.

Re: NSNotificationCenter with blocks considered harmful

#16

There's nothing really magical about this – don't cause retain cycles, everyone knows __block semantics changed with ARC, keep the returned value from the block-based NSNotificationCenter method, etc. Standard stuff. The only thing that surprised me was the reference cycle in NSAssert. Then again, given Apple's poor regard for TDD, that shouldn't surprise me.

Same here. Nothing special. Everything he mentions is not specific to NSNotificationCenter with block. One has to look out for these issues whenever one uses blocks.

The NSAssert macro caught me by surprise too.

Re: NSNotificationCenter with blocks considered harmful

#17

This really applies equally to any block that captures self. Blocks are, IMHO, the one place where ARC really falls down versus garbage-collection.

Yes, it's just a retain cycle. Self retains block, block retains self. The only thing that makes this case confusing is that self only holds the block implicitly (via the notification center instead of any obvious ivar). Otherwise it's a design pattern that every reference counted language user must understand to avoid memory leaks. Weak references to self in blocks are a very common design pattern that all Objective…

Using blocks is the one bit of Objective-C that still reminds me of the old MRR style. Just like with retain/release/autorelease, it's one thing understanding the pattern, it's another ensuring that your entire program conforms to it. Anywhere that you capture nontrivial objects is a possible failure point.

ReactiveCocoa has some nice patterns for avoiding block callbacks altogether. Eg:

   [myTarget rac_liftSelector:@selector(receiveCallback:) withSignals:mySignal, nil];
will capture a weak reference to the target, invoke the callback whenever 1 or more events fire and automatically unsubscribe when the target deallocates.

Re: NSNotificationCenter with blocks considered harmful

#18

There's nothing really magical about this – don't cause retain cycles, everyone knows __block semantics changed with ARC, keep the returned value from the block-based NSNotificationCenter method, etc. Standard stuff. The only thing that surprised me was the reference cycle in NSAssert. Then again, given Apple's poor regard for TDD, that shouldn't surprise me.

Another issue with NSAssert is that it's #ifdef-ed out in release mode.

So it can introduce reference cycles that only exist in debug mode, that prevent you from spotting premature deallocations that only become apparent in release mode.

(Of course, you QA in release mode. But it's annoying not catching that stuff early)

Re: NSNotificationCenter with blocks considered harmful

#19

There's nothing really magical about this – don't cause retain cycles, everyone knows __block semantics changed with ARC, keep the returned value from the block-based NSNotificationCenter method, etc. Standard stuff. The only thing that surprised me was the reference cycle in NSAssert. Then again, given Apple's poor regard for TDD, that shouldn't surprise me.

I agree and disagree.

For me, I agree this is standard stuff. If you are writing this stuff everyday, this block song and dance is basically taken care of with muscle memory.

Part of my job involves working with people from other companies who aren't as strong with objective-c. There are a lot of people that have trouble blocks for whatever reasons. I recently had a guy from another company act almost surprised that we were using "advanced features like blocks". We were a little shocked. But it just shows that not everyone is comfortable with them.

BUT, I think a better approach from the author wouldn't be to tell people not to use blocks w/ NSNotificationCenter but to make sure they know the in and outs of blocks, because blocks are amazingly powerful tools and they aren't going anywhere.

Re: NSNotificationCenter with blocks considered harmful

#20

There's nothing really magical about this – don't cause retain cycles, everyone knows __block semantics changed with ARC, keep the returned value from the block-based NSNotificationCenter method, etc. Standard stuff. The only thing that surprised me was the reference cycle in NSAssert. Then again, given Apple's poor regard for TDD, that shouldn't surprise me.

> everyone knows __block semantics changed Everyone except the authors of the "Blocks Programming Topics" and the authors of the AVCamCaptureManager sample code. Maybe. FYI the reason I included the digression about the __block change specifically is that I was recently fixing bugs on a project that uses AVCamCaptureManager, and Apple's mis-use of __block in that class, this is not a joke, through a series of corner…

Apple's sample code is terrible. I've always assumed it is written by interns because it is generally bug ridden and often not the right way to do something.
Post reply on HN