iPhone OS 3.2 - Как зарегистрироваться для уведомлений, которые могут быть недоступны - PullRequest
0 голосов
/ 16 апреля 2010

Итак, я пытаюсь зарегистрироваться для уведомления MPMoviePlayerDidExitFullscreenNotification в моем универсальном приложении (iPhone и iPad).

Проблема в том, что ОС 3.1.3 не поддерживает это уведомление и просто вылетает.

Я пробовал проверить версию, вот так:

if ([MPMoviePlayerController instancesRespondToSelector:@selector(setShouldAutoplay:)])
{//Check for shouldSetAutoplay, this ensures that we are running at least 3.2
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playerDidFinish:) name:(NSString*)class2 object:[self player]];

Не работает, все равно вылетает. Как мне это сделать?

Ответы [ 4 ]

2 голосов
/ 24 апреля 2010

Это также работает:

if (&MPMoviePlayerDidExitFullscreenNotification) {

}

Обратите внимание, что вы должны проверить адрес символа, иначе вы получите сбой.

2 голосов
/ 16 апреля 2010

Поскольку MPMoviePlayerDidExitFullscreenNotification является символом, он должен быть известен во время (динамического) соединения для любых версий. Проверка времени выполнения не помогает.

Чтобы решить эту проблему, вам нужно отложить загрузку этого во время выполнения. Вы можете использовать dlsym:

NSString* x_MPMoviePlayerDidExitFullscreenNotification
  = dlsym(RTLD_DEFAULT, "MPMoviePlayerDidExitFullscreenNotification");
if (x_MPMoviePlayerDidExitFullscreenNotification != nil) {
  [[NSNotificationCenter defaultCenter] addObserver:self ...];
}

В качестве альтернативы, вы можете сделать MPMoviePlayerDidExitFullscreenNotification слабым символом , поэтому, когда dyld не находит этот символ, вместо сбоя он просто устанавливает его в NULL.

Наконец, поскольку MPMoviePlayerDidExitFullscreenNotification является просто константной строкой, вы можете просто использовать

… name:@"MPMoviePlayerDidExitFullscreenNotification" …

Но содержимое этой строки - деталь реализации. Нет гарантии (хотя и редко), что Apple не изменит это на что-то другое в более поздних версиях.

1 голос
/ 14 июля 2010

Мне нужно было именно это, но я предпочел использовать dlsym, как предложил KennyTM, однако мне нужно было сделать небольшое изменение, чтобы оно работало, поэтому я думаю, что это ошибка (пожалуйста, исправьте меня, если я ошибаюсь). Вот фрагмент кода, который я использую, который прекрасно работает:

NSString* x_MPMoviePlayerDidExitFullscreenNotification = *(NSString**)dlsym(RTLD_DEFAULT, "MPMoviePlayerDidExitFullscreenNotification");
        if (x_MPMoviePlayerDidExitFullscreenNotification != nil) {
            [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didExitFullscreen:) name:x_MPMoviePlayerDidExitFullscreenNotification object: self.videoPlayer];
        }

Изменением во фрагменте KennyTM было *(NSString**) приведение после dlsym, так как кажется, что dlsym вернет указатель на символ.

1 голос
/ 16 апреля 2010

Чтобы ответить на ваш актуальный вопрос:

Вы должны иметь возможность зарегистрироваться для любого уведомления без сбоев. Как говорит Кенни, это символ, поэтому правильная регистрация для 3.2:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playerDidFinish:) name:MPMoviePlayerDidExitFullscreenNotification object:[self player]];

Для кода, который работает в 3.13, вы можете предположить, что этот символ является просто удобством для компилятора, и использовать вместо него строку:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playerDidFinish:) name:@"MPMoviePlayerDidExitFullscreenNotification" object:[self player]];

Вы тестируете, используя shouldAutoplay, все в порядке, хотя я бы предпочел все это непосредственно на экземпляре, который я бы использовал - т.е. Вероятно, ваша настоящая проблема - использовать class2 приведение к NSString в качестве имени уведомления.

...