diff --git a/content/technical/2011/12/fun-with-objc-setassociatedobject-and-uialertview.html b/content/technical/2011/12/fun-with-objc-setassociatedobject-and-uialertview.html new file mode 100644 index 0000000..e6dd257 --- /dev/null +++ b/content/technical/2011/12/fun-with-objc-setassociatedobject-and-uialertview.html @@ -0,0 +1,46 @@ +When it comes time to present errors or other messages in iOS with +[UIAlertView] it is immediately obvious that a more convenient interface +would involve the use of blocks. A [search on GitHub][github-search] +shows just about every iOS developer has had the same thought and had a crack at it. + +[UIAlertView]: http://developer.apple.com/library/ios/#documentation/uikit/reference/UIAlertView_Class/UIAlertView/UIAlertView.html +[github-search]: https://github.com/search?type=Repositories&language=&q=uialertview&repo=&langOverride=&x=14&y=17&start_value=1 + +After reviewing the better options (I.e. those that actually had a +README with more than a few lines of content) on GitHub it appeared +that one of the challenges was how to handle memory. This stems from +the wrapper becoming the delegate for the UIAlertView but not having a +strong reference from the caller. I saw various solutions to this, most +involving adding a extra retain call to keep everything around until the +delegate methods were called. + +Since my project is using ARC I looked for a solution that +didn't involve marking the wrapper file as non-ARC and +invoking `retain`. The solution I came up with was to use +[`objc_setAssociatedObject`][set-object]. This Objective-C runtime +function allows one object to be associated with another using various +memory management strategies. I used this to associate the UIAlertView +blocks based wrapper with the UIAlertView. + +[set-object]: http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/ObjectiveC/Chapters/ocAssociativeReferences.html + +In the `init` method the wrapper instance is associated with its UIAlertView: + + objc_setAssociatedObject(alertView, _cmd, self, OBJC_ASSOCIATION_RETAIN); + +Note that I'm using the implicit second argument to the method, its +selector, `_cmd` as the key for the associated object. This was +suggested in a [tweet by Bill Bumgarner][bbum]. + +[bbum]: http://twitter.com/bbum/status/3609098005 + +Then in `alertView:didDismissWithButtonIndex:`, the association +is removed, `dealloc` of the wrapper called as a result and the +`UIAlertView` also released. + + SEL key = @selector(initWithTitle:message:); + objc_setAssociatedObject(self.alertView, key, nil, OBJC_ASSOCIATION_RETAIN); + +The full [MIT licensed code][gist] is available as a [gist on GitHub][gist]. + +[gist]: https://gist.github.com/1392611 diff --git a/content/technical/2011/12/fun-with-objc-setassociatedobject-and-uialertview.yaml b/content/technical/2011/12/fun-with-objc-setassociatedobject-and-uialertview.yaml new file mode 100644 index 0000000..55f7f9f --- /dev/null +++ b/content/technical/2011/12/fun-with-objc-setassociatedobject-and-uialertview.yaml @@ -0,0 +1,14 @@ +--- +title: Fun With objc_setAssociatedObject and UIAlertView +extra: Solving memory management issues with objc_setAssociatedObject in a blocks based wrapper around UIAlertView. +kind: article +section: technical +created_at: 2011-12-08 08:02:00 +keywords: +- ios +- uialertview +- blocks +- objc_setAssociatedObject +- arc +- objective-c +