2010-04-16 18 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