問題タブ [method-swizzling]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票する
3 に答える
4599 参照

ios - カテゴリでメソッドを上書きするときに元の実装を呼び出す方法は?

私は物事が実際にどのように機能するかを理解しようとしています。そのため、カテゴリを使用して特定のメソッドを上書きすると、興味深いNSLogが得られると思いました。

スーパーとセルフはここでは機能しません。-hitTest:withEvent:の元の実装を呼び出す方法はありますか?UIViewで-hitTest:withEvent:が呼び出されるたびにNSLogが必要です。

それは個人的な学習目的のためだけです。イベント配信の様子を見たいです。

0 投票する
5 に答える
10306 参照

ios - Swift でのメソッド スウィズリング

UINavigationBar私が克服しようとしている小さな問題があります。ビュー コントローラーでメソッドを使用してステータス バーを非表示にprefersStatusBarHidden()すると (アプリ全体のステータス バーを無効にしたくありません)、ナビゲーション バーは、ステータス バーに属する高さの 20pt を失います。基本的にナビゲーションバーは縮小します。

ここに画像の説明を入力 ここに画像の説明を入力

さまざまな回避策を試していましたが、それぞれに欠点があることがわかりました。次に、メソッドのスウィズリングを使用して、この問題を解決するクラスに呼び出されるプロパティを追加するこのカテゴリに出会いましたObjective-C でテストしたところ、動作しました。元の Objective-C コードのヘッダー実装を次に示します。fixedHeightWhenStatusBarHiddenUINavigationBar

今は Swift でアプリを作成しているので、Swift に翻訳してみました。

私が最初に直面した問題は、Swift 拡張機能がプロパティを格納できないことでした。fixedHeightWhenStatusBarHiddenそのため、値を設定できるようにするプロパティを宣言するには、計算されたプロパティで解決する必要がありました。しかし、これは別の問題を引き起こします。どうやら、計算されたプロパティに値を割り当てることはできません。そのようです。

エラーCannot assign to the result of this expression が表示されます。

とにかく以下は私のコードです。エラーなしでコンパイルできますが、動作しません。

fixedHeightWhenStatusBarHidden()途中のメソッドはコメントアウトされています。これを残すと、メソッドの再宣言エラーが発生するためです。

これまで Swift や Objective-C でメソッドの入れ替えを行ったことがないため、この問題を解決するための次のステップがわからないか、まったく可能でさえありません。

誰かがこれに光を当てることができますか?

ありがとうございました。


更新 1: newacct のおかげで、プロパティに関する最初の問題が解決されました。しかし、コードはまだ機能しません。load()エクステンションで実行がメソッドに到達していないことがわかりました。この回答のコメントから、あなたのクラスは の子孫でNSObjectある必要があることを学びました。ですから、なぜこれがまだ機能していないのかわかりません。もう 1 つのオプションは追加ですが、Swift では拡張機能に追加することはできません。以下は、更新されたコードです。UINavigationBarNSObjectNSObjectProtocol@objc

問題はまだ未解決です。


更新 2: Jasper は目的の機能を実現するのに役立ちましたが、明らかにいくつかの大きな欠点があります。

load()ジャスパーが示唆したように、拡張機能のメソッドが起動していなかったため、次のコード ブロックをアプリ デリゲートのdidFinishLaunchingWithOptionsメソッドに移動しました。

また、プロパティのゲッターで戻り値を「true」にハードコーディングするfixedHeightWhenStatusBarHidden必要がありました。アプリのデリゲートでスウィズリング コードが実行されるようになったため、View Controller から値を設定することはできません。これにより、再利用性に関しては拡張機能が冗長になります。

したがって、問題はまだ多かれ少なかれ未解決です。誰かがそれを改善するアイデアを持っているなら、答えてください。

0 投票する
2 に答える
490 参照

objective-c - スタブ - [NSDate init]

NSDate をスタブ化してモックの日付を返すことは、-[NSDate init] 以外のカテゴリを使用して簡単に実行できます。- [NSDate init] は、他のメソッドとは異なり呼び出されません。class_addMethod は役に立ちません。-[NSDate init] の method_exchangeImplementations、method_setImplementation は実際には -[NSObject init] を変更しますが、-[NSDate init] には影響しません。

出力は

NSDate+Mock.m

0 投票する
2 に答える
633 参照

ios - Objective-c IOS arm64 メソッドのスウィズリングが元のメソッドの呼び出しに失敗する

私はARMv7 IOSデバイスで標準的な方法のスウィズリングを使用していますが、それは私にとって完璧に機能します.

しかし、arm64 用にコードをコンパイルすると、新しいメソッドから元のメソッドを呼び出すことができません。

スウィズリングの主な目的 - アプリケーションの内部メソッドのパラメーターを別のメソッドで使用すること。

元のメソッドがあり、それを変更して新しいメソッドで元のメソッドを呼び出し-(void)insertdata:(id)textたいです。-(void)patchedCall:(id)text

コード:

arm64 アーキテクチャで元のメソッドを呼び出すと、コードが失敗します。

armv7 と arm64 の両方で動作するようにコードを改善するにはどうすればよいですか?

0 投票する
0 に答える
168 参照

ios - Objective-C クラス識別子には、_OBJC_CLASS_$_ の代わりに objc_class_ がプレフィックスとして付けられます

Objective-C で作成されたアプリケーションでいくつかのメソッドをスウィズルしようとしています。次のエラーが表示されます。

Hopper で実行可能ファイルを開くと、代わりにすべてのクラスに接頭辞が付いていることがわかりますobjc_class_。したがって、私がスウィズルしようとしているメソッドのクラス名はobjc_class_IASAvatarViewController. まず、クラス識別子がどのようにそのようになったのか知りたくてたまりません (ある種の名前マングリング?)。次に、dylib が正しい識別子を参照できるかどうかを知りたいです。

DylibTest.h:

DylibTest.m

そして、Objective-C クラスを含むホッパーのスクリーン ショット: ホッパーのスクリーンショット

編集:画像を直接投稿するのに十分な評判を得ました.

Edit2: class-dumpファイルの: http://pastebin.com/DcUD5AL5

0 投票する
1 に答える
283 参照

ios - UICollectionViewCell メソッドの入れ替え

UITableViewCellカテゴリのメソッドをスウィズルしているときに予期しない動作が発生する

私の.mファイル:

さて、私がプロジェクトを開始するとき、私はこれを持っています:

  1. これは 100%UICollectionViewCellカテゴリです。
  2. この時点で、クラス+(void) loadのみUITableViewCellが渡されます (予想どおり)
0 投票する
1 に答える
330 参照

objective-c - pickerView:numberOfRowsInComponent メソッドを pickerView の 1 つのインスタンスに置き換える方法

プログラムで pickerView を作成し、pickerView:numberOfRowsInComponent のような独自のバージョンのメソッドを使用させたいと考えています。

実行時に次のようにインスタンスを作成します。

呼び出される標準的なメソッドは次のとおりです。

私がやりたいのは、この標準メソッドをこのインスタンス専用の別のメソッドに置き換えることです。

メソッド swizzle を使用して他のことでこれを行うことができましたが、UIPickerView で動作させることができないようです。

}

実行時に 2 番目のメソッドがインスタンスに追加され、それがリストに含まれているかどうかを確認するために、メソッドをリストしました。

ただし、2 番目の方法は実行されず、1 番目の方法は実行されます。

これを始めた投稿へのリンクは次のとおりです。動作することを確認しましたが、これについて何かが欠けているようです。 http://nshipster.com/method-swizzling/

私が解決しようとしている問題は、同時に実行される別のインスタンスに依存しない UIPickerView オブジェクトのインスタンスを作成したいということです。したがって、1 つのインスタンスでのみ機能し、実行中の可能性のある他のインスタンスを完全に無視する別の方法が必要であり、これをプログラムで実行したいと考えています。

タグ/スイッチを使用しない理由の少なくとも 1 つは、実行時まで条件がどうなるかわからないことです。

スウィズルがあるオブジェクトで機能し、別のオブジェクトで機能しない理由がわかりません。また、実行時にストック メソッドを他のオブジェクトに置き換える他の方法を受け入れることもできます。

私が置き換えようとしている方法について、それを置き換えることができない何かがありますか?

編集:質問を明確にするために、リンク内の次のコードが機能します。あるメソッドを別のメソッドに交換します。私がする必要があるのは、別のオブジェクトに対して同じことであり、あるオブジェクトでは機能するが別のオブジェクトでは機能しないことを理解できません。

これは別のオブジェクトでも機能します: http://nshipster.com/method-swizzling/

ここにも別のリンクがあります: http://blog.newrelic.com/2014/04/16/right-way-to-swizzle/