[英]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
。
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.