如何使用ARC在iOS 7中释放私有属性

ban*_*ndw 5 iphone objective-c ios automatic-ref-counting

我正在使用ARC在iOS 7上开发一个项目,我想在发布viewController时发布一个私有属性
这是作为模态视图控制器呈现的TestViewController,将值设置为viewDidLoad中的私有属性testAVPlayer:

//TestViewController.m
#import "TestAVPlayer.h"
@interface TestViewController () {
    TestAVPlayer *testAVPlayer;
}

@end

- (void)viewDidLoad
{
    [self setupPlayer];
}

- (void)setupPlayer {
    AVPlayerItem *item = [AVPlayerItem playerItemWithURL:[[NSBundle mainBundle] URLForResource:@"music" withExtension:@"mp3"]];
    testAVPlayer = [TestAVPlayer playerWithPlayerItem:item];

    [testAVPlayer setActionAtItemEnd:AVPlayerActionAtItemEndNone];
    [testAVPlayer play];
}

- (void)dealloc {
    NSLog(@"dealloc TestViewController: %@", self);
}
Run Code Online (Sandbox Code Playgroud)

TestAVPlayer是AVPlayer的子类,我把一个NSLog放入dealloc

// TestAVPlayer.h
#import <AVFoundation/AVFoundation.h>

@interface TestAVPlayer : AVPlayer

@end

//  TestAVPlayer.m
#import "TestAVPlayer.h"

@implementation TestAVPlayer

- (void)dealloc {
    NSLog(@"dealloc testAVPlayer: %@", self);
}
@end
Run Code Online (Sandbox Code Playgroud)

当TestViewController被解雇时,testAVPlayer似乎永远不会被释放,我看到"dealloc TestViewController",但是在控制台日志中没有"dealloc testAVPlayer"

Bed*_*ord 10

我想你的代码,但问题是,即使你调用[TestAVPlayer playerWithPlayerItem:item]TestAVPlayer类没有这样的方法,所以它会调用playerWithPlayerItem:函数从AVPlayer基类,将返回的实例AVPlayer类来代替的TestAVPlayer类.编译器不会给你任何警告,因为该playerWithPlayerItem:方法返回一个类型id.如果使用调试器检查这一点,您将看到私有变量的类型不是TestAVPlayer:

在此输入图像描述

deallocTestAVPlayer,因为没有这样的对象创建将永远不会被调用.在AVPlayer该实例时被释放TestViewController被释放.您可以使用Instruments或仅添加符号断点来检查[AVPlayer dealloc].

选择Breakpoint Navigator并单击+按钮并添加符号断点.

[AVPLayer dealloc]符号场,然后按Enter.当您运行应用程序并TestViewController获取释放时,您将看到断点将被命中,因此AVPlayer真正被解除分配.


小智 5

您正在使用类工厂方法初始化对象,这意味着您不拥有testAVPlayer对象,因此不负责释放它.

有关详细信息,请参阅Objective-C编程指南中的概念中的类工厂方法.

如果您确实想拥有并控制此对象的生命周期,请使用以下初始值设定项:

testAVPlayer = [[TestAVPlayer alloc] initWithPlayerItem:item];
Run Code Online (Sandbox Code Playgroud)

并且将调用您的dealloc方法.