我正在编写一个从影片剪辑中提取帧的应用程序。我设计它,以便提取将在一个单独的线程上完成,以防止应用程序冻结。提取过程本身占用了大量资源,但在模拟器中使用时效果很好。但是,在为iPad构建时存在问题。当我执行另一个动作(我告诉我的AV播放器在我提取帧时播放)时,线程意外停止工作,我相信它正在被杀死。
我认为这是因为我使用了大量资源,但并不完全确定。
以下是我的问题: 1.如何判断我的线程是否停止? 2.如果它真的来自过度处理我该怎么办?我真的需要这个行动来实施。
下面是一些使用的代码: 要创建线程:
[NSThread detachNewThreadSelector:@selector(startReading) toTarget:self withObject:nil];
我会发布您需要的任何信息, 非常感谢!
更新 我现在正在使用GCD,它为我填充了线程。然而,操作系统仍然杀死线程。
我确切知道它何时发生。当我告诉我的[AVplayer play];它杀死了线程。
此问题仅发生在实际的iPad而不是模拟器上
答案 0 :(得分:1)
听起来我正在尝试同时解码两个视频片段。由于iPad的基于硬件的解码特性,它一次只能支持一个解码过程。当您播放新项目时,旧项目将被取消。这可以解释为什么它在模拟器中工作,但不在设备上工作。
对于解决方案,您可以切换到纯libav(GPL)或CoreAVC SDK(商业)等软件解码器。这样你就不会干扰HW解码器的播放。
答案 1 :(得分:0)
当某些东西在模拟器中起作用并且在设备上不起作用时,一个明显的解释是资源约束问题。但有时模拟器也无法准确模拟设备运行的其他方面。所以我想知道是否可以对这种情况进行任何其他解释。我有一种可能性,即它可以竞争有限的资产 - 访问AV资产 - 这意味着当你开始播放它时,它也不再可用于处理(并且由于某种原因,模拟器中的错误)不显示此限制。)
在AV Foundation Programming Guide, under "Playing Assets" Apple州:
虽然最终您想要播放资源,但您不会直接向AVPlayer对象提供资源。相反,您提供了AVPlayerItem的实例。玩家物品管理与其相关联的资产的呈现状态。播放器项目包含播放器项目轨道 - AVPlayerItemTrack的实例 - 与资产中的轨道相对应。
这种抽象意味着你可以同时使用不同的玩家玩一个给定的资产,但每个玩家以不同的方式呈现。例如,使用项目轨道,您可以在播放期间禁用特定轨道(您可能不想播放声音组件)。
所以我想知道 - 您是否正在使用AVPlayerItem来访问您的资产,这会让两个操作同时发生?如果是这样,至少排除了那个具体方向。但如果没有,可能值得调查,看它是否解决了这个问题。
可以抓住稻草。但可能会在某个地方领先。
答案 2 :(得分:0)
在Apple的线程编程指南的“设置线程的堆栈大小”一节中,第27页说:
在iOS和Mac OS X v10.5及更高版本中,分配并初始化 NSThread对象(不要使用detachNewThreadSelector:toTarget: withObject:method)
尽管在第22页中说detachNewThreadSelector
是使用NSThread创建线程的方法之一。
它在第23页给出了如何启动线程的示例:
NSThread* myThread = [[NSThread alloc] initWithTarget:self selector:@selector(myThreadMainMethod:) object:nil];
[myThread start];
根据将在您的应用中创建分离主题的指南。尝试以这种方式创建你的线程,看看操作系统是否停止杀死你的线程。
此处参考指南的链接
在第29页中还提到,如果你的应用程序使用托管内存模型,那么在你的线程入口例程中创建一个自动释放池应该是你做的第一件事,并且类似地破坏它你的线程做的最后一件事。不确定这不会导致你的线程被杀,但是要确认你这样做。
在你的线程入口例程中有一个try / catch块可能无法解决kill问题但是,如果你的线程中发生错误,将避免你的app退出。
我忘了提及这个可以帮助你解决资源限制的其他设计技巧,正如Duncan所说。根据指南第18页:
避免共享数据结构
避免与线程相关的资源的最简单,最简单的方法 冲突是为程序中的每个线程提供自己的副本 无论需要什么数据。并行代码最小化时最有效 你的线程之间的沟通和资源争用。
其中,我认为你可以在你的应用中做到这一点。除了做Duncan提到的“不直接向AVPlayer对象提供资源,而是提供AVPlayerItem的实例”之外,还要为每个线程创建单独的实例,为播放器线程创建一个AVPlayerItem实例,为一个AVPlayerItem实例创建一个AVPlayerItem实例。提取线程。