From 7d409d737dbfb4bec0978db2bc015bcda0e7f332 Mon Sep 17 00:00:00 2001 From: Wesley Moore Date: Thu, 8 Dec 2011 17:37:31 +1100 Subject: [PATCH] Add Fun With objc_setAssociatedObject and UIAlertView --- ...c-setassociatedobject-and-uialertview.html | 45 +++++++++++++++++++ ...c-setassociatedobject-and-uialertview.yaml | 14 ++++++ 2 files changed, 59 insertions(+) create mode 100644 content/technical/2011/12/fun-with-objc-setassociatedobject-and-uialertview.html create mode 100644 content/technical/2011/12/fun-with-objc-setassociatedobject-and-uialertview.yaml 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..65d976b --- /dev/null +++ b/content/technical/2011/12/fun-with-objc-setassociatedobject-and-uialertview.html @@ -0,0 +1,45 @@ +When it comes time to present errors or other messages with UIAlertView +it becomes immediately obvious that a more convienient interface would +involve the use of blocks. A [search on GitHub][github-search] shows +just about every developer has had a crack at it. + +[github-search]: TODO + +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]: TODO + +In the `init` method: + + 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 Bummager][bbum]. + +[bbum]: http://twitter.com/bbum/status/3609098005 + +Then in `alertView:didDismissWithButtonIndex:`, the assocation is +removed, `dealloc` of the wrapper called 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]: 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 +