2011-11-07 47 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(商业版)。这样你就不会干扰硬件解码器的播放。

相关问题