2011-11-07 46 views
6

我目前正在編寫一個從影片剪輯中提取幀的應用程序。我設計了它,以便提取將在單獨的線程上完成,以防止應用程序凍結。提取過程本身需要大量資源,但在模擬器中使用時工作良好。但是,爲iPad構建時存在問題。當我執行另一個動作(我告訴我的AV播放器在抽取幀時播放)時,線程意外停止工作,並且我相信它正在被殺死。線程正在被操作系統殺死

我認爲這是因爲我使用了大量的資源,但並不完全確定。

以下是我的問題: 1.如何判斷/爲什麼我的線程停止? 2.如果真的是過度處理,我應該怎麼做?我真的需要這個行動來實施。

繼承人使用一些代碼即時通訊: 要創建線程:

[NSThread detachNewThreadSelector:@selector(startReading) toTarget:self withObject:nil];

我會後你需要, 感謝這麼多的任何信息!

更新 我現在在使用GCD,它爲我填充了線程。但是操作系統仍然會殺死線程。

我確切知道它在什麼時候發生。當我告訴我的[AV播放器播放];它殺死了線程。

這個問題只有在實際的iPad,而不是在模擬器上

+0

如果您不得不問,請嘗試使用更高級別的抽象,例如調度隊列(GCD)或操作隊列(NSOperationQueue)。請參閱[移離線程](http://developer.apple.com/library/mac/#documentation/General/Conceptual/ConcurrencyProgrammingGuide/ConcurrencyandApplicationDesign/ConcurrencyandApplicationDesign.html#//apple_ref/doc/uid/TP40008091-CH100- SW8)進行擴展討論,或者查找[GCD](http://stackoverflow.com/questions/7941860/#7941898)或[NSOperationQueue](http://stackoverflow.com/questions/830218/)示例。這是非常有用的東西。 – Jano

+1

你的應用崩潰了嗎?如果是的話,崩潰報告說什麼?你確定AVPlayer是線程安全的嗎?因爲如果您在調用[AVplayer play]並在後臺線程中同時訪問它,那可能是問題所在。 – JeanLuc

+0

您的提取線程是否作爲後臺線程運行?我正在學習Objective-C,但是,如果你能夠將它作爲後臺線程運行,可以幫助不被操作系統殺死。 –

回答

0

當一些工作在模擬器和設備上不起作用發生,一個顯而易見的解釋是肯定的資源約束問題。但有時模擬器無法準確模擬設備功能的其他方面。所以我想知道是否可以有任何其他的解釋。我發現一種可能性是它可能會對有限的資產進行競爭 - 訪問AV資產 - 這意味着當您開始播放它時,它不再可用於處理(並且由於某種原因,模擬器中的錯誤不顯示此限制)

AV Foundation Programming Guide, under "Playing Assets"蘋果指出:雖然最終要播放的資產

,你不能直接到AVPlayer對象提供的資產。相反,您提供了AVPlayerItem的實例。玩家項目管理與其相關聯的資產的呈現狀態。玩家項目包含播放器項目軌道 - AVPlayerItemTrack的實例 - 對應於資產中的軌道。

這個抽象意味着你可以同時使用不同的玩家玩一個給定的資產,但是每個玩家以不同的方式渲染。使用項目軌道,例如,您可以在播放過程中禁用特定曲目(您可能不想播放聲音組件)。

所以我想知道你是否使用AVPlayerItems來訪問你的資產,這會讓這兩個操作一次發生?如果是這樣,至少該特定方向被排除。但是,如果不是,可能值得調查,看看它是否能解決問題。

可以抓在吸管上。但可能會導致某處。

+0

現在我知道,事實上,當我用這個資產啓動AVPlayer後,當我從資產中讀取幀時,線程正在停止,但我該如何繞過? –

+0

如果您未通過AVPlayerItem訪問資產,則應提供一個AVPlayerItem實例以播放資產,並提供第二個AVPlayerItem實例以從資產中讀取幀。這應該允許兩者同時發生。 –

+0

我使用AVPlayer資產播放資產,但不讀取幀。對於那個使用AVAssetReader的即時通訊,它是由資產本身啓動的。你會如何建議這樣做? –

0

在節「設置線程的堆棧大小」的蘋果的線程編程指南,第27頁說:

在iOS和Mac OS X的v10.5及其更高版本,分配和初始化一個 NSThread對象(不要使用detachNewThreadSelector:toTarget: withObject:方法)

即使在第22頁說:detachNewThreadSelector是創建使用NSThread線程的方式之一。

它給出瞭如何開始你的線程23頁下面的例子:

NSThread* myThread = [[NSThread alloc] initWithTarget:self selector:@selector(myThreadMainMethod:) object:nil]; 
[myThread start]; 

根據該會在您的應用程序分離線程的指南。嘗試以這種方式創建你的線程,看看操作系統是否停止殺死你的線程。

僅供參考這裏是鏈接到引導

http://developer.apple.com/library/ios/iPad/#documentation/Cocoa/Conceptual/Multithreading/CreatingThreads/CreatingThreads.html#//apple_ref/doc/uid/10000057i-CH15-SW2

它也提到了29頁,如果您的應用程序使用管理的內存模型,這似乎是你,創造你的線程自動釋放池入門例程應該是你做的第一件事,並且同樣地將它毀掉你的線程所做的最後一件事。不知道沒有這會導致你的線程死亡,但確認你這樣做。

在線程入口例程中有一個try/catch塊可能無法解決kill問題,但是,如果在線程中發生錯誤,將會避免您的應用程序退出。

我忘記提及這個其他設計提示,可以幫助您解決資源限制問題,正如Duncan提到的那樣。據導遊介紹第18頁:

避免共享數據結構

避免線程相關的資源 衝突的最簡單和最簡單的方法是給每個線程在你的程序自己的副本的 任何數據就需要。當您最小化線程間的通信和資源爭用時,並行代碼效果最佳。

其中,我認爲你可以在你的應用程序中做到這一點。除了做鄧肯提到的「不直接向AVPlayer對象提供資產,而是提供AVPlayerItem的實例」之外,還要爲每個線程創建單獨的實例,爲播放器線程創建一個AVPlayerItem實例,併爲其創建一個AVPlayerItem實例提取線程。

1

這聽起來像你正試圖解碼兩個視頻剪輯在同一時間。由於iPad的基於硬件的解碼特性,它一次只能支持一個解碼過程。當您播放一個新的項目時,舊的將被取消。這可以解釋爲什麼它可以在模擬器中工作,但不能在設備上工作。至於解決方案,您可以切換到純粹的軟件解碼器,如libav(GPL)或CoreAVC SDK(商業版)。這樣你就不會干擾硬件解碼器的播放。