2010-04-16 52 views
0

因此,我正在尝试在我的通用应用程序(iPhone和iPad)中注册MPMoviePlayerDidExitFullscreenNotification通知。iPhone OS 3.2 - 如何注册可能不可用的通知

问题是,OS 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]]; 

不工作时,仍然崩溃。我该怎么做呢?

回答

2

由于MPMoviePlayerDidExitFullscreenNotification是一个符号,因此必须在任何版本的(动态)链接时间都知道它。运行时间检查并没有帮助。

为了解决这个问题,你需要延迟加载到运行时间。你可以使用dlsym

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

或者,你可以做MPMoviePlayerDidExitFullscreenNotification a weak symbol所以当dyld没有找到该符号,而不是崩溃它只是将其设置为NULL。

最后,由于MPMoviePlayerDidExitFullscreenNotification只是一个字符串常量,你可以简单地使用

… name:@"MPMoviePlayerDidExitFullscreenNotification" … 

但该字符串的内容是实现细节。没有任何保证(尽管很少),苹果公司不会在以后的版本中将其改为其他方式。

+0

是的,这正是发生了什么事情。 我只是用字符串而不是常量。希望没有什么变化...... ;-) 谢谢! – cdstamper 2010-04-16 13:32:44

1

要回答你的实际问题:

你应该能够注册任何通知,而不会崩溃。正如Kenny所说,这是一个符号,所以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

您的测试是好的,但我我宁愿直接使用我将要使用的实例 - 即[self player]。这可能是你真正的问题是使用class2转换为NSString作为通知名称。

+0

谢谢,使用@“MPMoviePlayerDidExitFullscreenNotification”而不是const作品太棒了! – cdstamper 2010-04-16 13:31:08

2

这也适用于:

if (&MPMoviePlayerDidExitFullscreenNotification) { 

} 

注意你必须检查符号的地址,否则你会得到一个崩溃。

1

我需要这个,但我更喜欢使用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的片段的变化是对dlsym后*(NSString**)投,因为它似乎对dlsym会返回一个指向符号。

+0

虽然我认为你是对的,dlsym会返回一个指向符号的指针(所以指向NSString *的指针),是不是在这里解除引用空指针以防dlsym返回0? – Stephan 2012-08-18 12:34:14

+0

这太棒了!谢谢你。 – defactodeity 2013-02-25 16:29:43