その後のその後

iOSエンジニア 堤 修一のブログ github.com/shu223

【iOS7】AsyncImageView が arm64 でクラッシュする件

AsyncImageView を arm64 で動かすと EXC_BAD_ACCESS でクラッシュする件の対処法です。


結論から言うと、objc_msgSend をキャストするよう修正すればOKです。


たとえばこれを、

objc_msgSend(connection.target, connection.success, image, connection.URL);


こうします *1

((void(*)(id, SEL, id, id))objc_msgSend)(connection.target, connection.success, image, connection.URL);

情報ソース

objc_msgSend 関数の修正方法については、公式ドキュメントの『64ビット移行ガイド』で説明されています。

An exception to the casting rule described above is when you are calling the objc_msgSend function or any other similar functions in the Objective-C runtime that send messages. Although the prototype for the message functions has a variadic form, the method function that is called by the Objective-C runtime does not share the same prototype. The Objective-C runtime directly dispatches to the function that implements the method, so the calling conventions are mismatched, as described previously. Therefore you must cast the objc_msgSend function to a prototype that matches the method function being called.


Listing 2-14 shows the proper form for dispatching a message to an object using the low-level message functions. In this example, the doSomething: method takes a single parameter and does not have a variadic form. It casts the objc_msgSend function using the prototype of the method function. Note that a method function always takes an id variable and a selector as its first two parameters. After the objc_msgSend function is cast to a function pointer, the call is dispatched through that same function pointer.

Updating Your App from 32-Bit to 64-Bit Architecture | Apple Developer Documentation

その他

あとでプルリク送ってみようと思いますが、本家リポジトリはiOS7リリース後の更新はなく、マージしてくれないかもしれません。


ちょうど何日か前に、




こんなやり取りがあったのですが、やっぱり SDWebImage に乗り換えた方がいいかなと、今回の件で思いました。


メンテされてるかどうか、はOSSの善し悪しの判断基準としてトップに来ると思いますが、iOSの場合はとくに『メジャーアップデート後にメンテされているか』が重要かなと。


*1:これ以外に、何カ所かあります。引数の数に合わせてキャストの記述を変更してください。