[AVAssetWriterInput requestMediaDataWhenReadyOnQueue:usingBlock:]的内存问题 [英] Memory problems with [AVAssetWriterInput requestMediaDataWhenReadyOnQueue:usingBlock:]

查看:1683
本文介绍了[AVAssetWriterInput requestMediaDataWhenReadyOnQueue:usingBlock:]的内存问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个库,使用AVFoundation将资源导出到文件中。我创建了一个阅读器,一个编写器,将输入和输出连接到这些,然后在输入上调用 requestMediaDataWhenReadyOnQueue 方法来开始提取数据。提供给此方法的块回调看起来有点像这样:

I’m writing a library to export assets to a file using AVFoundation. I create a reader, a writer, connect the inputs and outputs to these and then call the requestMediaDataWhenReadyOnQueue method on the inputs to start pulling the data. The block callback supplied to this method looks a bit like this:

[input requestMediaDataWhenReadyOnQueue:queue usingBlock:^{
    while ([input isReadyForMoreMediaData]) {
        CMSampleBufferRef buffer;
        // The track has some more data for us
        if ([reader status] == AVAssetReaderStatusReading
               && (buffer = [output copyNextSampleBuffer])) {
            BOOL result = [input appendSampleBuffer:buffer];
            CFRelease(buffer);
            if (!result) {
                // handle error
                break;
            }
        // The track is finished, for whatever reason
        } else {
            [input markAsFinished]; ⬅
            switch ([reader status]) {
                // inspect the status and act accordingly
            }
        }
    }
}];

这在iOS 5上完美运行,但在iOS 4上,代码在EXC_BAD_ACCESS之后死亡,标记为⬅箭头。经过一番探索之后,我觉得在将输入标记为完成后,块会立即以某种方式被销毁。在执行坏行之前完全有效的 self 指针会以某种方式变成 0xfff ... 或某些垃圾值,如调试器。但之前指向它的对象很好,正如僵尸工具所证实的那样,它没有被解除分配。

This works perfectly on iOS 5, but on iOS 4 the code dies from EXC_BAD_ACCESS after the line marked with the ⬅ arrow. After some poking around I feel like the block was somehow destroyed immediately after marking the input as finished. The self pointer that’s perfectly valid before executing the bad line somehow turns into 0xfff… or some garbage value as reported by the debugger. But the object pointed to it before is fine, as confirmed by the zombies tool, it does not get deallocated.

我缺少什么?

推荐答案

看到相同(类似)的问题。 iOS5开心,iOS4.3.5,不开心。有兴趣了解你最终找到的东西。

Seeing the same (similar) issue. iOS5 happy, iOS4.3.5, not happy. Interested to learn what you ultimately find.

通过在requestMedatWhenReadyOnQueue块之前明确保留writer,writer输入,reader,reader输出并明确释放所有四个来解决它。 else子句的结尾。

Got around it by explicitly retaining writer, writer input, reader, reader output before the requestMedatWhenReadyOnQueue block and explicitly releasing all four at the very end of the else clause.

文档确实说标记完成后,块应该退出。也许他们不是在开玩笑。如果您执行除退出之外的任何操作,则会出错。上面的解决方法似乎有效。

The doc does say that after marking finished, "The block should then exit." Maybe they are not kidding. If you do anything other than exit, it is an error. The above workaround seems to work though.

更新:我仍然发现即使在保留和释放所有资产对象后它偶尔也会崩溃。正如您的问题所指出的那样,在您将编写器输入标记为已完成之后不久就会崩溃,就好像块本身正在被释放一样。而不是仅仅将块作为函数的一部分传递。我创建了一个复制的块属性,它是长期存在的对象的一部分。我用Block_copy初始化它,只在长寿命对象的析构函数中释放它。这似乎可以解决问题。我从那以后没有看到任何4.3.5崩溃。

UPDATE: I still found that it occasionally crashed even after retaining and releasing all of the asset objects. As your question observes, it crashes shortly after you mark the writer input as finished it is as if the block itself is being deallocated. Rather than just pass the block as part of the function. I create a copied block property that is part of a long lived object. I initialize it with Block_copy and only release it in the destructor of the long lived object. This seems to do the trick. I haven't seen any 4.3.5 crashes since.

这篇关于[AVAssetWriterInput requestMediaDataWhenReadyOnQueue:usingBlock:]的内存问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆