2

私が現在作業しているアプリケーションは、通常のNSSliderを使用してQuickTimeムービー内の位置を制御しています。そこにあるすべてのメディアプレーヤーと同じように。

スティッキー/グルーコードを避けるために、スライダーの値をムービーの位置(0から1の範囲)にバインドしたかったのです。

UIでスライダーをドラッグすると、右側のセッターが呼び出されますが、プログラムで値を変更しても、何らかの理由でスライダーが更新されません。私はバインディングの原則とKVCがどのように機能するかを理解していると言えます。また、プログラムで値を変更する場合は、ゲッターまたはセッターを使用するか、[self willChangeValueForKey:@"theKey"]および[selfdidChangeValueForKey:@"theKey"]でオブザーバーに通知する必要があることも知っています。

何らかの理由で、これはまだ機能しません。ゲッターにはいくつかのログステートメントもあります。一度も呼ばれません!

この振る舞いの理由が何であるか、私は本当に自分自身を説明することはできません。オンライン(およびAaron Hillegassの本)にある単純な例とは少し異なる唯一のことは、単純なキーの代わりにキーパスを使用していることです。

IBから、activeMovieプロパティを持つAppDelegateに移動します。activeMovieは、moviePositionプロパティを持つクラスVS_Movieのインスタンスです。したがって、私のキーパスは次のとおりです。self.activeMovie.movi​​ePositionこれもXcodeが検出するようです。

ヒントやサポートを提供していただければ幸いです。前もって感謝します

これが私が使用しているいくつかのコードです:

1.プロパティ宣言

// ivar
NSNumber* _moviePosition;

// Property
@property (retain) NSNumber* moviePosition;

2.ゲッターとセッターの実装

- (NSNumber*) moviePosition
{
    NSLog(@"MoviePosition returned : %lf", [_moviePosition doubleValue]);
    return _moviePosition;
}

- (void) setMoviePosition:(NSNumber*)newPos
{
    NSLog(@"New MoviePosition : %lf", [newPos doubleValue]);

    if ( _moviePosition && [newPos isEqualToNumber:_moviePosition] )
        return;

    if ( _moviePosition ) 
       [_moviePosition release];

    _moviePosition = [newPos retain];

    if ( _positioningReady )
    {
        _positioningReady = NO;

        TimeValue newMovieTime = (TimeValue)([_moviePosition doubleValue] * 
                                             (double)_clipDurationTimeValue);
        SetMovieTimeValue(_qtMovie, newMovieTime);
        [_movieView displayCurrentFrameOfMovie:self];

        // Post a notification to inform the observing 
        // classes so they can do the neccessary handling.
        NSNotificationCenter* nc = [NSNotificationCenter defaultCenter];
        [nc postNotificationName:VS_MoviePositionChangedNotification 
                      object:self];
    }
}

3.関数の呼び出し

- (void) setTimeValue:(TimeValue) value withTimeScale:(TimeScale) scale
{
    SetMovieTimeValue(_qtMovie, value);
    SetMovieTimeScale(_qtMovie, scale);

    double newMoviePosition = (double)GetMovieTime(_qtMovie, NULL) / (double)_clipDurationTimeValue;
    [self setMoviePosition:[NSNumber numberWithDouble:newMoviePosition]];

    [_movieView displayCurrentFrameOfMovie:self];
}
4

1 に答える 1

1

プロパティが呼び出されるとするとmoviePosition、ゲッターが呼び出され-moviePosition(アンダースコアなし)、セッターが呼び出される必要があります-setMoviePosition:(アンダースコアなしで、プロパティ名の最初の文字が大文字になります)。

@propertyあなたは宣言を示さなかった。セッターとゲッターの名前を指定することは許可されていますが、KVCもKVOもそれに注意を払っていません。それらの場合、命名規則に従う必要があります。Key-Valueコーディングプログラミングガイド:単純な属性のアクセサ検索パターンを参照してください。

あなたが主張するように、正しいセッターが呼ばれていると確信していますか?アクセサメソッドの名前を間違えたため、コンパイラはそれらをそのように認識しません。したがって、@synthesizeは適切な名前のものを生成しています。それらはKVCによって呼び出されています(そしてKVOによってフックされています)。

それはまた、あなたのメソッドと一致しない-setTimeValue:withTimeScale:呼び出しを回避している理由でもあります。ただし、を期待するセッターにを渡すため、警告(および実行時にクラッシュ)が発生するはずです。[self setMoviePosition:newMoviePosition]-set_moviePosition:doubleNSNumber*

于 2012-05-18T00:51:46.123 に答える