From 7d409d737dbfb4bec0978db2bc015bcda0e7f332 Mon Sep 17 00:00:00 2001 From: Wesley Moore Date: Thu, 8 Dec 2011 17:37:31 +1100 Subject: [PATCH 1/4] 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 + From 5a622afda58919cfc1e56284d74b5e47d1e870e4 Mon Sep 17 00:00:00 2001 From: Wesley Moore Date: Fri, 9 Dec 2011 07:35:04 +1100 Subject: [PATCH 2/4] Add missing links and a couple more TODOs --- ...jc-setassociatedobject-and-uialertview.html | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) 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 index 65d976b..4f50def 100644 --- a/content/technical/2011/12/fun-with-objc-setassociatedobject-and-uialertview.html +++ b/content/technical/2011/12/fun-with-objc-setassociatedobject-and-uialertview.html @@ -1,9 +1,11 @@ -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. +When it comes time to present errors or other messages in iOS +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 iOS developer has had a +crack at it. -[github-search]: TODO +[UIAlertView]: TODO +[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 @@ -21,7 +23,7 @@ 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 +[set-object]: http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/ObjectiveC/Chapters/ocAssociativeReferences.html In the `init` method: @@ -29,7 +31,7 @@ In the `init` method: 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]. +suggested in a [tweet by Bill Bummager][bbum]. TODO [bbum]: http://twitter.com/bbum/status/3609098005 @@ -40,6 +42,6 @@ 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. +The full [MIT licensed code][gist] is available as a [gist on GitHub][gist]. [gist]: https://gist.github.com/1392611 From 468e89693aa30b75d663c3d61ea5131d1ece8d34 Mon Sep 17 00:00:00 2001 From: Wesley Moore Date: Fri, 9 Dec 2011 07:41:06 +1100 Subject: [PATCH 3/4] Fix spelling --- .../12/fun-with-objc-setassociatedobject-and-uialertview.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 index 4f50def..03be06f 100644 --- a/content/technical/2011/12/fun-with-objc-setassociatedobject-and-uialertview.html +++ b/content/technical/2011/12/fun-with-objc-setassociatedobject-and-uialertview.html @@ -1,6 +1,6 @@ When it comes time to present errors or other messages in iOS with [UIAlertView] it becomes immediately obvious that a more -convienient interface would involve the use of blocks. A [search on +convenient interface would involve the use of blocks. A [search on GitHub][github-search] shows just about every iOS developer has had a crack at it. @@ -35,7 +35,7 @@ suggested in a [tweet by Bill Bummager][bbum]. TODO [bbum]: http://twitter.com/bbum/status/3609098005 -Then in `alertView:didDismissWithButtonIndex:`, the assocation is +Then in `alertView:didDismissWithButtonIndex:`, the association is removed, `dealloc` of the wrapper called and the `UIAlertView` also released. From f79cbb3b56a8612e21dd47b579a2d3f82f37d8d2 Mon Sep 17 00:00:00 2001 From: Wesley Moore Date: Sun, 11 Dec 2011 17:23:08 +1100 Subject: [PATCH 4/4] Finish off UIAlertView post --- ...c-setassociatedobject-and-uialertview.html | 21 +++++++++---------- 1 file changed, 10 insertions(+), 11 deletions(-) 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 index 03be06f..e6dd257 100644 --- a/content/technical/2011/12/fun-with-objc-setassociatedobject-and-uialertview.html +++ b/content/technical/2011/12/fun-with-objc-setassociatedobject-and-uialertview.html @@ -1,10 +1,9 @@ -When it comes time to present errors or other messages in iOS -with [UIAlertView] it becomes 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 a -crack at it. +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]: TODO +[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 @@ -25,19 +24,19 @@ 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: +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 Bummager][bbum]. TODO +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 and the `UIAlertView` also -released. +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);