приложение, над которым я сейчас работаю, контролирует положение в фильме QuickTime с помощью обычного NSSlider. Как и в любом другом медиаплеере.
Я хотел привязать значение ползунка к положению фильма (которое находится в диапазоне от 0 до 1), чтобы избежать липкого/клеевого кода.
Когда я перетаскиваю ползунок в пользовательском интерфейсе, вызывается правильный установщик, но по какой-то причине ползунок не обновляется, когда я изменяю значение программно. Я бы сказал, что понимаю принципы привязки и то, как работает KVC. И я также знаю, что вы должны либо использовать геттеры, либо сеттеры, либо уведомлять наблюдателей с помощью [self willChangeValueForKey:@"theKey"] и [self didChangeValueForKey:@"theKey"] при программном изменении значений.
Почему-то это все еще не работает. У меня также есть несколько операторов журнала в геттере. Его даже не называют ни разу!
Я не могу себе объяснить, в чем может быть причина такого поведения. Единственное, что немного отличается от простых примеров, найденных в Интернете (и в книге Аарона Хиллегасса), заключается в том, что я использую ключевой путь вместо простого ключа.
Из IB я перехожу к App Delegate, у которого есть свойство activeMovie. ActiveMovie — это экземпляр класса VS_Movie со свойством moviePosition. Итак, мой ключевой путь: self.activeMovie.moviePosition, который, похоже, также находит 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];
}
activeMove
в классе делегатов приложения, так и дляmoviePosition
в классеVS_Movie
. Кроме того, что вы на самом деле используете, сеттеры или-will/DidChangeValueForKey:
? Если последнее, покажите код, который это делает. Обновляется ли позиция в фоновом потоке? Наконец, почему вы не используете встроенные представления видеоплеера/контроллера? - person Ken Thomases   schedule 18.05.2012