使用AVQueuePlayer的静态初始化程序的奇怪内存行为

时间:2014-05-21 16:13:26

标签: ios objective-c memory-management automatic-ref-counting

我已声明属性

@property(nonatomic, strong) AVQueuePlayer *player;

当我使用+ queuePlayerWithItems:初始化它时,如果我分配给player新对象或nil,则不会取消分配。即使我在下面的一行之后立即行动。当我使用player初始化– initWithItems:时,一切都按预期工作。我用ARC。是bug还是静态初始化器自动释放还是有什么区别?我记得ARC之前的时间就像

+ (AVQueuePlayer *)queuePlayerWithItems:(NSArray *)items
{
    return [[[AVQueuePlayer alloc] initWithItems:items] autorelease];
}

那是怎么回事?

1 个答案:

答案 0 :(得分:0)

使用ARC,您的代码可能如下所示:

+ (AVQueuePlayer *)queuePlayerWithItems:(NSArray *)items 
{
    return [[AVQueuePlayer alloc] initWithItems:items];
}

编译器可能仍将创建的对象放入自动释放池中。是否发生这种情况还取决于优化集的级别,以及method family是否被正确识别。

您可以帮助编译器声明如下方法:

+ (AVQueuePlayer *)queuePlayerWithItems:(NSArray *)items NS_RETURNS_RETAINED;

这将导致编译器假定该方法返回一个已分配的对象,并在适当时需要发送一条平衡的release消息,而不是将该对象放入自动释放池中。

NS_RETURNS_RETAINED将扩展为__attribute__((ns_returns_retained))

定义应省略属性NS_RETURNS_RETAINED

编辑:

如果这不是您的方法,并且您无法更改声明,则可以使用显式自动释放池来删除自动释放的对象:

{
    AVQueuePlayer* player;
    @autoreleasepool {
       // the next line retains the returned object:
       player = [AVQueuePlayer queuePlayerWithItems:items];
    }  // here, the autorelease pool releases the returned object (it's still alive)
    // do something with variable player:
    ...
    [player ...];  // last usage of variable player
    // now, the last reference to player ceases to exist, it gets released and deallocated

}