简体   繁体   English

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

[英]Strange memory behaviour with static initializer of AVQueuePlayer

I have declared property 我已经申报财产

@property(nonatomic, strong) AVQueuePlayer *player;

and when I initialize it with + queuePlayerWithItems: it is not deallocated if I assign to player new object or nil. 当我使用+ queuePlayerWithItems:初始化它时+ queuePlayerWithItems:如果我分配给player新对象或nil,则不会释放它。 Even if I do it right after one row below. 即使我在下面一行之后马上做。 When I initialize player with – initWithItems: everything works as expected. 当我使用– initWithItems:初始化player– initWithItems:一切正常。 I use ARC. 我使用ARC。 Is it bug or are not static initializers autoreleasing or what is the difference? 是bug还是不是静态初始化程序会自动释放,或者有什么区别? I remember the times before ARC when it would be like 我记得ARC之前的时代

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

So what is the matter? 那怎么了?

With ARC your code may like look as this: 使用ARC,您的代码可能看起来像这样:

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

The compiler may still put the created object into an autorelease pool, though. 但是,编译器仍可以将创建的对象放入自动释放池中。 Whether or not this happens also depends on the level of optimization set, and whether the method family is correctly recognized. 是否发生这种情况还取决于优化集的级别以及方法族是否正确识别。

You can help the compiler declaring the method like this: 您可以帮助编译器声明如下方法:

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

This will cause the compiler to assume that the method returns an allocated object and needs to be sent a balanced release message when appropriate, instead to put the object into the autorelease pool. 这将导致编译器假定该方法返回一个分配的对象,并且需要在适当的时候发送平衡的release消息,而不是将该对象放入自动释放池中。

NS_RETURNS_RETAINED will expand to __attribute__((ns_returns_retained)) NS_RETURNS_RETAINED将扩展为__attribute__((ns_returns_retained))

The definition should omit the attribute NS_RETURNS_RETAINED . 该定义应省略属性NS_RETURNS_RETAINED

Edit: 编辑:

If this is not your method and if you cannot change the declaration, you may use an explicit autorelease pool to get rid of the autoreleased object: 如果这不是您的方法,并且您不能更改声明,则可以使用显式的自动释放池来摆脱自动释放对象:

{
    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

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM