7

私は Objective-C が初めてで、Apple のドキュメントに基づいてシングルトン クラスを作成しようとしています。

+ (MyGizmoClass*)sharedManager
{
    if (sharedGizmoManager == nil) {
        sharedGizmoManager = [[super allocWithZone:NULL] init];
    }
    return sharedGizmoManager;
}

+ (id)allocWithZone:(NSZone *)zone
{
    return [[self sharedManager] retain];
}

このコードsharedManagerには、このクラスのオブジェクトが存在するかどうかをチェックする静的メソッドがあります。そうであれば、以前に作成されたオブジェクトを返し、それ以外の場合は新しいオブジェクトを作成します。

いくつか質問があります:

  1. が静的な場合sharedManager、どのようにアクセスできますsuperか?

  2. 印刷する[super class]と、現在のクラス名が表示されるのはなぜですか?

  3. [[super allocWithZone:NULL] init]が現在のクラス オブジェクトを返すのはなぜですか?

  4. superここに等しい場合self、現在のクラスを呼び出さないのはなぜallocWithZone:(NSZone *)zoneですか?

4

3 に答える 3

3

(1.) super「静的関数」には何がありますか? Objective-C では、+メソッドは適切にクラス メソッドと呼ばれ、-メソッドはインスタンス メソッドと呼ばれます。これらのメソッドは真の静的メソッドではありません。これは、Objective-C クラス自体がClassという不透明な型のオブジェクトであるためです。したがって、superとの両方selfが +methods で定義されます。MyGizmoClasssuperのスーパークラスにメッセージを送信しますが、 +method から呼び出されると同等の +method を探し、 -method から呼び出されると対応する -method を探します。+MyGizmoClass のメソッドでクラスであるMyGizmoClass返しますsupersuper
self、一方で -methodsselfMyGizmoClassインスタンスへのポインターです。

(2.) メソッドは を+class返しますself.isa。Yesはスーパークラスの :メソッドを[super class]呼び出しますが、が +methods に渡されると、その値も型も変更されません (一方、の型は、-methods を介して渡されるとスーパークラスにキャストされます)。したがって、チェーンの上位にあるメソッドの実装が を要求すると、同じ値MyGizmoClassが取得されます。確かに、オーバーライドを配置できるMyGizmoSuperClassからMyGizmoClassを派生させることで、スーパークラスを呼び出すことを確認できます。+classselfself+classself.isa
super+class

    @interface MyGizmoSuperClass : NSObject
    @end
    @implementation MyGizmoSuperClass
    +(Class) class {
        NSLog(@"yes it calls MyGizmoSuperClass:class");
        return [super class];
    }
    @end
    @interface MyGizmoClass : MyGizmoSuperClass 
    +(Class) classviasuper;
    @end
    @implementation MyGizmoClass
    +(Class) classviasuper {
        return [super class]; //which version of class will super call?
    }
    @end
    int main(int argc, char *argv[])
    {
       NSLog(@"returned %@",[MyGizmoClass classviasuper]); 
    }

版画

はい、それは MyGizmoSuperClass を呼び出します:クラス
は MyGizmoClass を返しました

(3.)superのスーパークラス バージョンを再度呼び出しますallocWithZoneself、メソッドに渡される値は引き続きMyGizmoClassを指し、allocWithZoneレシーバーのクラスのオブジェクトを返すため、MyGizmoClassが返されます。

super(4.)が と異なることを簡単に確認できますself[self allocWithZone:NULL]コードを実装すると、 MyGizmoClassの実装が呼び出され、allocWithZone無期限にループします。では[super allocWithZone:NULL]、スーパークラスのバージョンが呼び出されます。

于 2013-08-05T21:17:25.947 に答える
3

他の回答は、シングルトンに関する良い情報を指摘していますが、実際にはあなたの質問には答えていません。あなたの質問は実際にはほとんどオブジェクト指向に基づいています.シングルトンを具体的に参照しているという事実は偶発的です.

  1. を参照してこの質問に答えましたself。ここに、答えの重要な部分を言い換えます

    superクラス レベルのコンテキストでは意味がありますが、インスタンスではなく、スーパークラス自体を参照します。

  2. これも私を捨てていました。この質問をしたところ、次のように結論付けられました。

    [super class]super現在のインスタンス (つまり)のメソッドを呼び出しますself。self にオーバーライドされたバージョンがある場合、それが呼び出され、見た目が異なります。オーバーライドしないため、呼び出し[self class]は の呼び出しと同じ[super class]です。

  3. 実際にこのクラスのインスタンスを返していると確信していますか? sharedGizmoManagerそれとも、このクラスのインスタンスに割り当てていますか?

  4. Super は self と同じではありませんが、呼び出したメソッドの一部: たとえば[super class]、呼び出すメソッドの同じ実装を[self class]呼び出しています。

于 2012-08-06T12:29:25.673 に答える