iOS-EXC_BAD_ACCESS代码=1 UIWebView在(方法swizzling)初始化后崩溃



我刚刚将我的应用程序切换到ARC。由于Xcode提供的重构工具,转换部分成功。唯一不起作用的部分是一个奇怪的错误。

我使用了方法swizzling(method_exchangeImplementations),这样它就不会调用UIView的initWithFrame,而是调用我的myInitWithFrame代码。重构过程在myInitWithFrame的方法声明处引发错误,因此我在方法声明后添加了__属性__((objc_method_family(init)))。现在,这一切在iOS 6.0及以上版本上都很好,但在iOS 5.0(我想支持的最低iOS)上却不起作用。我得到一个EXC_BAD_ACCESS(代码=1,地址=0X28)。每次运行时,都会出现完全相同的内存地址。

我有一个UIWebView,它称之为:

[[UIWebView alloc] initWithFrame:webViewFrame];

myInitWithFrame完成初始化后,返回self,然后崩溃。在线程跟踪中,它表示它在[UIWebView retain]方法上的苹果代码中崩溃(该方法变灰),如下所示。

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

很抱歉,线程跟踪的格式不太好,我没有足够的代表来发布图像。

为什么同样的代码适用于iOS 6.0,但不适用于iOS 5.0?

这个问题很难解决。事实上,这个问题只出现在iOS 5上,而没有出现在iOS 6上,这是我第一次表明这可能是苹果的问题,或者是方法问题。经过大约一周的搜索,我达成了共识,我应该给苹果技术支持发电子邮件,看看他们是否能帮助我解决这个问题。

他们的回答是这都是我们的错。他说,在iOS 5中,UIWebView会跟踪它自己的保留计数(使用UIWebViewInternal类),我的方法swizzling是在对象完全初始化之前保留它,这导致了崩溃。当我不使用ARC时,这并不是一个问题,因为我从未在init函数中调用retain,但使用ARC,它会在"认为"合适的时候添加retain。他提到,在iOS 6中,UIWebViews不管理自己的保留计数,这就是它在iOS 6上工作的原因。

最新更新