4

今日、私は のすべてのインスタンスに対して代替メソッドを「エイリアス」したいプロジェクトに取り組んでいましたが、古き良きメソッドのスウィズリングNSArrayではそれほど難しいとは思いませんでした。

私はJRSwizzleを始めて…</p>

[NSArray jr_swizzleMethod:@selector(objectAtIndex:) withMethod:@selector(objectAtIndex_accordingToMe:) error:nil];

NSArray明確にするために、これを適切なカテゴリ on 、 と呼ばれるインスタンス メソッドと組み合わせましたobjectAtIndex_accordingToMe:

ただし、同じ古​​い index で、同じ古いオブジェクトを取得していました。はぁ。最終的に、エラーをスローしていないにもかかわらず、クラスクラスターであるため、これらの結果を達成できないことがわかりましたNSArray

私の質問は、「これ」が実際にNSArrayメソッドをオーバーライドしようとする道の終わりであることを受け入れたくないということだと思います。つまり、これはNSArray..人々はそれをいじりたがっているに違いありません。Apple の基礎クラスは、世界中のスウィズラーにとって主要なターゲットになると考える人もいるでしょう。

それで、変更、エイリアス、monkey-patch、オーバーライド、またはその他の方法で…NSArrayなどを(サブクラス化せずに)使用する方法はありますか?

4

2 に答える 2

4

それはクラスのクラスターであるというだけではありません。NSArrayは無料で にブリッジされてCFArrayおり、Core Foundation をスウィズルすることはできません。したがって、これが一般的に機能する可能性はほとんどありません。

しかし、あなたは何を解決しようとしていますか?新しいメソッドを追加する場合は、カテゴリを使用します。それらはクラス クラスタで問題なく動作します。NSArray の一部のビルトインの動作を変更することは、災害のレシピのようです (演習としては面白いかもしれません)。

先に進む前に、少なくとも CFArray.c を見て、基礎となるもののいくつかがどのように実装されているかを理解したいと思うでしょ


編集: 実稼働コードでこれを行うことは決してありませんが、ISA スウィズリングで個々の配列インスタンスをハイジャックすることで、必要なものの一部を取得できます。コード例については、 ISASwizzleを参照してください。コードの説明はiOS:PTLの 20 章にあります。「isa swizzle」を検索すると、ネット上でさらに多くの情報が見つかるはずです。それがKVOの実装方法です。しかし、NSArray では...うわー、それは壊れやすいです。

于 2012-08-01T02:06:56.573 に答える
3

おそらく、この動作が必要な特定の配列があるでしょう。それが何であれ、そのインスタンスのクラス オブジェクトを取得し、非常に簡単に入れ替えることができます。

[[myArray class] jr_swizzleMethod:@selector(objectAtIndex:) withMethod:@selector(objectAtIndex_accordingToMe:) error:nil];

の具体的なサブクラスもいくつかありNSArrayます。

NSArray * trees = [NSArray array];
NSArray * birds = [NSArray arrayWithObjects:@"Albatross", @"Budgerigar", @"Cardinal", nil];
NSMutableArray * dogs = [NSMutableArray arrayWithObjects:@"Airedale", @"Beagle", @"Collie", nil];

NSLog(@"%@ %@ %@", [trees class], [birds class], [dogs class]);

__NSArrayI最初の 2 つと__NSArrayM3 番目を取得するため、潜在的に(これは非常に脆弱です)、ランタイム関数を使用してクラス オブジェクトを名前で取得できます。

[objc_getClass("__NSArrayI") jr_swizzleMethod:@selector(objectAtIndex:) withMethod:@selector(objectAtIndex_accordingToMe:) error:nil];
于 2012-08-01T02:06:13.163 に答える