iPhoneSDKでペン先で作成されたオブジェクトのクラスを変更しようとしています。
この理由は次のとおりです。実行時まで、nibオブジェクトをどのクラスにするかはわかりません(ただし、同じUIViewベースのスーパークラスがあります)。また、不測の事態ごとに異なるnibを作成したくありません。.nibは1つのオブジェクトのクラスを除いて、それぞれについて同じです。
私はいくつかの方法で成功しましたが、いくつかのノックオン効果があるか、私が使用した方法がどれほど安全かわからない:
方法1:スーパークラスでallocをオーバーライドし、ac変数を必要なクラスに設定します。
+ (id) alloc {
if (theClassIWant) {
id object = [theClassIWant allocWithZone:NSDefaultMallocZone()];
theClassIWant = nil;
return object;
}
return [BaseClass allocWithZone:NSDefaultMallocZone()];
}
これはうまく機能し、「合理的に」安全だと思いますが、ペン先のクラスIDとして正しいクラスのペン先がある場合、またはサブクラスを自分で割り当てます(「theClassIWant」を設定せずに)-基本クラスのオブジェクト創造された。また、allocをオーバーライドするというアイデアは本当に好きではありません...
方法2:initWithCoderでobject_setClass(self、theClassIWant)を使用します(スーパークラスでinitWithCoderを呼び出す前に):
- (id) initWithCoder:(NSCoder *)aDecoder {
if (theClassIWant) {
// the framework doesn't like this:
//[self release];
//self = [theClassIWant alloc];
// whoa now!
object_setClass(self,theClassIWant);
theClassIWant = nil;
return [self initWithCoder:aDecoder];
}
if (self = [super initWithCoder:aDecoder]) {
...
これもうまく機能しますが、すべてのサブクラスが必ずしもスーパークラスと同じサイズになるとは限らないため、これは非常に危険な場合があります。これに対抗するために、initWithCoder内でリリースして正しいタイプに再割り当てしようとしましたが、フレームワークから次のエラーが発生しました。
「このコーダーでは、置き換えられたオブジェクトをinitWithCoderから返す必要があります:」
これが何を意味するのかよくわからないでください!initWithCoderのオブジェクトを置き換えています...
これらの方法の有効性に関するコメント、または改善や代替案の提案を歓迎します!