Question

I just switched my app over to ARC. The transition was a partial success thanks to the refactoring tool that Xcode provides. The one part that doesn't work is a strange error.

I used method swizzling (method_exchangeImplementations) so that instead of calling UIView's initWithFrame, it will call my myInitWithFrame code. The refactoring process threw an error at the method declaration of myInitWithFrame, so I added the __attribute__((objc_method_family(init))) after the declaration of the method. Now this all works perfectly fine for iOS 6.0 and above, but on iOS 5.0 (the lowest iOS I would like to support) it doesn't work. I'm getting an EXC_BAD_ACCESS (code=1, address=0X28). On every run the exact same memory address comes up.

I have a UIWebView that calls it's:

[[UIWebView alloc] initWithFrame:webViewFrame];

After the myInitWithFrame does it's initialization, it returns self, then it crashes. On the thread trace, it says that it crashes in apples's code (the method is greyed out) on the [UIWebView retain] method, as seen below.

Thread 1, Queue : com.apple.main-thread
#0  0x3515a7d2 in -[UIWebView retain] ()
#1  0x316ddef4 in objc_retain ()
#2  0x0011528c in -[UIView(style) myInitWithFrame:]

Sorry that the thread trace isn't very well formatted, I don't have enough rep to post an image.

Is there any reason why the same code works for iOS 6.0, but not iOS 5.0?

Was it helpful?

Solution

This issue was very complicated to fix. The fact that this issue only showed up on iOS 5, and not iOS 6 was my first indication that this may be an apple issue, or an method swizzling issue. After about a week of searching I came to the consensus that I should email Apple technical support, to see if they could help me with this issue.

Their response was that it's both our faults. He said that in iOS 5 UIWebView keeps track of it's own retain count (using a UIWebViewInternal class), and that my method swizzling was retaining the object before it was fully initialized, and that caused the crash. When I didn't use ARC it wasn't an issue, because I never call retain in the init function, but with ARC it adds retains as it "sees" fit. He mentioned that in iOS 6 the UIWebViews don't manage their own retain count, and that's why it worked in iOS 6.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top