forked from wezm/wezm.net
Merge branch 'rpalertview' into deploy
This commit is contained in:
commit
7c39f48ae2
2 changed files with 60 additions and 0 deletions
|
@ -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
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue