2

我目前正在使用的应用程序正在使用普通的 NSSlider 控制 QuickTime 电影中的位置。就像那里的每个媒体播放器一样。

我想将滑块的值绑定到电影位置(在 0 到 1 范围内)以避免粘/胶水代码。

当我在 UI 中拖动滑块时,会调用正确的设置器,但由于某种原因,当我以编程方式更改值时滑块不会更新。我会说我了解绑定的原理以及 KVC 的工作原理。而且我也知道,当您以编程方式更改值时,您必须使用 getter 或 setter,或者您必须使用 [self willChangeValueForKey:@"theKey"] 和 [self didChangeValueForKey:@"theKey"] 通知观察者。

由于某种原因,这仍然不起作用。我在 getter 中也有一些日志语句。它甚至没有被调用一次!

我无法真正解释自己这种行为的原因可能是什么。唯一的一点是,这与在网上找到的简单示例(以及在 Aaron Hillegass 的书中)有点不同的是,我使用的是密钥路径而不是简单的密钥。

从 IB 到 App Delegate,它有一个 activeMovie 属性。activeMovie 是类 VS_Movie 的一个实例,它有一个 moviePosition 属性。所以我的关键路径是:self.activeMovie.movi​​ePosition Xcode 似乎也能找到。

我将不胜感激提供的任何提示和帮助!提前致谢

这是我正在使用的一些代码:

一、财产申报

// ivar
NSNumber* _moviePosition;

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

2.getter和setter实现

- (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,getter 应该被调用-moviePosition(没有下划线)并且 setter 应该被调用-setMoviePosition:(没有下划线并且属性名的第一个字母大写)。

你没有出示@property声明。虽然允许指定 setter 和 getter 的名称,但 KVC 和 KVO 都没有注意这一点。对于他们来说,它需要遵循命名约定。请参阅键值编码编程指南:简单属性的访问器搜索模式

您确定您声称的调用了正确的二传手吗?因为您错误地命名了您的访问器方法,所以编译器无法识别它们。因此,@synthesize正在生成正确命名的。那些被 KVC 调用(并被 KVO 钩住)。

这也是为什么不使用与您的方法不匹配的-setTimeValue:withTimeScale:调用而逃脱的原因。但是,您应该会收到警告(并且在运行时会出现崩溃),因为您将 a 传递给期望.[self setMoviePosition:newMoviePosition]-set_moviePosition:doubleNSNumber*

于 2012-05-18T00:51:46.123 回答