iOSシミュレーターでUIPickerViewハングを削除する方法

シミュレータのUIPickerViewでアイテムを選択しようとすると、時々フリーズすることがあります。 しかし、現在ブレーキが表示されている限り、観察するのは耐え難いものになっています。「ドラム」の選択された要素の変更には最大1分かかり、その間、インターフェイスは何にも応答しません。



おそらくこれはベータ版の欠陥です。

特にこの問題の研究のためのクリーンなプロジェクトでは、すべてがまったく同じです。



この問題は、4つの起動オプションでテストされました。

Xcode 6.4 + 8.1 が表示されます

Xcode 6.4 + 8.3 マニフェスト自体

Xcode 7.0 + 8.3 マニフェスト自体

Xcode 7.0 + 9.0 が表示されない



シミュレーターのバージョンのパフォーマンスにわずかな不一致があることを示唆しています。この場合、症状の非常に迷惑なバージョンです。



問題を修正してみましょう。



「ドラム」が追加されたかなり単純なプロジェクトを開始します。

画像



そして今、私たちはリストを少し巻き上げようとします。

その結果、彼はこの位置で、この場合は28秒間フリーズします。

画像



さて、彼が何を考えているのか見てみましょう。

一時停止してバックトレースを監視します。

画像



この機会ヒーローにはAudioServicesPlaySystemSoundがあります。

どうやら、驚くことはないでしょう。なぜなら、インターネットは長い間、シミュレーターでサウンドを再生するという特別な態度に満ちているからです。 マクロがシミュレーターに関連する再生呼び出しをオフにすることを勧めるまで、マクロからのドロップはほぼ予想されるためです。



ここで無効にしてみましょう。 システムフレームワーク内から呼び出されるため、もちろん直接オフにすることはできません。 ただし、チェーンをもう少し高くしてみてください。



より正確には、 _playClickIfNecessaryメソッドを呼び出します。 名前を見て、私はこの方法がサウンドを再生する以外の何物でもないことを提案しようと思います。 実装を独自のものに置き換えるために残っていますが、それは単に何もしません。



例のために、アプリケーションのロード中に正しいものを作成してみましょう。

たとえば、AppDelegate内。



#if TARGET_IPHONE_SIMULATOR - (void)UIPickerTableView__playClickIfNecessary { // nothing to do } #endif + (void)initialize { # if TARGET_IPHONE_SIMULATOR Class srcClass = self; Class dstClass = NSClassFromString(@"UIPickerTableView"); if (srcClass && dstClass) { SEL srcSelector = NSSelectorFromString(@"UIPickerTableView__playClickIfNecessary"); SEL dstSelector = NSSelectorFromString(@"_playClickIfNecessary"); Method srcMethod = class_getInstanceMethod(srcClass, srcSelector); Method dstMethod = class_getInstanceMethod(dstClass, dstSelector); method_exchangeImplementations(srcMethod, dstMethod); } # endif }
      
      







私はカテゴリを介して交換しようとしましたが、失敗しました:

-テーブルを介して-その実装はUIPickerTableViewと重複するため。

-UIPickerTableViewを使用。通常、非表示APIをインポートできなかったため。



いずれにせよ、実装を置き換える方法はそれほど重要ではありません。

主なものは、交換後、すべてがブレーキやフリーズなしで機能するようになったことです。



しかし、問題を取り除くためのより簡潔な方法を誰かが確実に知っているのであれば、コメントの追加に非常に満足しています。 なぜなら30分でGoogleに賢明なものを見つけることができなかったからです。



UPD。 コメントは、より簡潔な方法を提案しました。



 Method m = class_getInstanceMethod(objc_lookUpClass("UIPickerTableView"), sel_getUid("_playClickIfNecessary")); method_setImplementation(m, imp_implementationWithBlock(^(id _self){}));
      
      






All Articles