0

NSTimerを使用して、クラスのスーパークラスの関数を呼び出そうとしています。

この関数は、次のように呼び出すと機能します。

[super playNarrationForPage:[NSNumber numberWithInt:1]];

しかし、私がこれを行う場合:

NSTimer *narrationTimer = [NSTimer scheduledTimerWithTimeInterval:7.5
                                                           target:self.superclass
                                                           selector:@selector(playNarrationForPage:) 
                                                           userInfo:[NSNumber numberWithInt:1] 
                                                           repeats:NO
                          ];

このエラーが発生します:unrecognized selector sent to class 0x106890 2012-07-06 21:14:59.522 MyApp[19955:707] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '+[MyBaseClass playNarrationForPage:]: unrecognized selector sent to class 0x106890'

superとして設定してみましたtarget:が、「未申告の識別子スーパーの使用」と言われました。何かご意見は?

4

3 に答える 3

9

self.superclassオブジェクトを返すのでClass、それは間違いなくあなたが望むものではありません。

また、NSTimer呼び出しがどのようにターゲットを呼び出すかを理解していないようです。NSNumberタイマーとしてを使用していてuserInfo、メソッドは引数playNarrationForPage:を期待しているようです。NSNumberしかし、anは、ターゲットを呼び出すときに引数としてそれを渡しNSTimerません!userInfo次のように、NSTimerパス自体が引数として渡されます。

// self is the NSTimer object here!
[self.target performSelector:self.selector withObject:self];

タイマーが呼び出す新しいメソッドを作成する必要があります。この新しいメソッドは、次のように、タイマーを引数として取る必要があります。

- (void)narrationTimerDidFire:(NSTimer *)timer {
    [self playNarrationForPage:timer.userInfo];
}

次に、タイマーを作成するときにそのセレクターを使用する必要があります。

NSTimer *narrationTimer = [NSTimer scheduledTimerWithTimeInterval:7.5
    target:self
    selector:@selector(narrationTimerDidFire:)
    userInfo:[NSNumber numberWithInt:1]
    repeats:NO];

narrationTimerDidFire:本当に呼び出したい場合は[super playNarrationForPage:]、コンパイラが許可します。しかし、それを行うのは非常に怪しいです。サブクラスでオーバーライドしていない場合は、直接playNarrationForPage:参照する理由はありません。superサブクラスはそのスーパークラスのメソッドを継承しますplayNarrationForPage:サブクラスをオーバーライドした場合playNarrationForPage:、タイマーのコールバックからサブクラスをバイパスすると、デザインに問題があることを示します。

于 2012-07-06T20:28:05.993 に答える
5

使用する必要があるのは、メソッド内にいて、同じメソッドのスーパークラスの実装を呼び出したい場合のみです(間接的に含む-以下を参照)。super

self.superclassスーパークラスでクラスメソッドを呼び出すことが目標でない限り、タイマーのターゲットとしては意味がありません。

selfターゲットとして使用するだけです。オーバーライドplayNarrationForPage:していて、superの呼び出しを遅らせたいためにそれが機能しない場合は、次のような別のメソッドを作成します。

- (void) _delayedDoIt
{
     [super playNarrationForPage:1];
}

playNarrationForPage:そして、タイマーを介しての自己の実装からそれを呼び出します。

于 2012-07-06T20:26:15.807 に答える
4

メソッドを呼び出すように直接指示することはできませんsupertargetはオブジェクトへのポインタにすぎず、インスタンスsuperとは別のポインタアドレスはありませんself

また、あなたにを割り当てることによってtarget、クラスになるようにself.superclass指示しています。targetしたがって、実行しようとしているのは、インスタンスメソッドではなく、クラスメソッドを呼び出すことです。

これを行う唯一の方法は、ターゲットを割り当てselfて、次のような別のメソッドを使用することです。

- (void)callSuperMethod
{
    [super playNarrationForPage:[NSNumber numberWithInt:1]];
}
于 2012-07-06T20:27:44.097 に答える