2013-07-09 117 views
3

我刚刚将我的应用程序切换到ARC。由于Xcode提供的重构工具,转换部分成功。一部分不起作用是一个奇怪的错误。iOS - EXC_BAD_ACCESS code = 1 UIWebView崩溃后(方法swizzling)初始化

我使用方法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做它的初始化之后,返回自我,然后崩溃。 在线程追踪上,它表示它在[UIWebView保留]方法中在苹果的代码中崩溃(方法灰显),如下所示。

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?

回答

5

此问题修复起来非常复杂。这个问题只出现在iOS 5上,而不是iOS 6上,这是我的第一个迹象,那就是这可能是苹果问题,或者是一种方法悬而未决的问题。经过大约一周的搜索后,我达成了一个共识,即我应该通过电子邮件向Apple技术支持发送电子邮件,以了解他们是否可以帮助解决此问题。

他们的回答是,这都是我们的错。他说,在iOS 5中,UIWebView会记录它自己的保留计数(使用一个UIWebViewInternal类),并且我的方法调整是在完全初始化之前保留对象,并导致崩溃。当我没有使用ARC时,它不是问题,因为我从来没有在init函数中调用retain,但是使用ARC时,它会在“看到”适合时保留。他提到,在iOS 6中,UIWebViews不管理自己的保留计数,这就是它在iOS 6中工作的原因。