How to free private property in iOS 7 using ARC

I am developing a project on iOS 7 using ARC, I want to release private property when releasing viewController
Here is the TestViewController, which is presented as a modal view controller, setting the value of the private property testAVPlayer property to viewDidLoad:

//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); } 

TestAVPlayer is a subclass of AVPlayer, I put NSLog in 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 

When TestViewController is rejected, testAVPlayer seems to never be released, I see "dealloc TestViewController", but there is no "dealloc testAVPlayer" in the console log

+5
source share
5 answers

I tried your code, the problem is that even if you call [TestAVPlayer playerWithPlayerItem:item] , the TestAVPlayer class TestAVPlayer not have such a method, so it calls the playerWithPlayerItem: function from the AVPlayer base class, which will return an instance of the AVPlayer class instead of the TestAVPlayer class. The compiler will not give you any warnings, because the playerWithPlayerItem: method returns an id type. If you check this with the debugger, you will see that the type of the private variable is not TestAVPlayer:

enter image description here

dealloc TestAVPlayer will never be called because no such object was created. The AVPlayer instance is freed when the TestViewController freed. You can check this with the tools or just add a Symbolic breakpoint in [AVPlayer dealloc] .

Select the breakpoint navigator and click the + button and add a Symbolic breakpoint.

Type [AVPlayer dealloc] in the Symbol field and press Enter. When you start the application, and TestViewController gets released, you will see that the breakpoint is deleted, so AVPlayer really freed.

+10
source

You use the factory class method to initialize your object, which means that you do not own the testAVPlayer object and, therefore, are not responsible for releasing it.

For more information, see factory class Methods from Concepts in Objective-C Programming Guide.

If you really want to own and manage the lifetime of this object, use the following initializer:

 testAVPlayer = [[TestAVPlayer alloc] initWithPlayerItem:item]; 

and the dealloc method will be called.

+5
source

testAVPlayer = [AVPlayer playerWithPlayerItem:playerItem];

You are using AVPlayer , not TestAVPlayer .

+2
source

Try to implement - viewDidUnload , then nil testAVPlayer :

 - (void) viewDidUnload { [super viewDidUnload]; testAVPlayer = nil; } 
+1
source

Although you name it [TestAVPlayer playerWithPlayerItem:item] , you do return an instance of AVPlayer , not TestAVPlayer . In fact, the AVPlayer instance you created is actually freed. You cannot see your log in dealloc because an instance of this class is never created.

As suggested by others, replace [TestAVPlayer playerWithPlayerItem:item] with [[TestAVPlayer alloc] initWithPlayerItem:item]; and you should start browsing your magazines.

+1
source

Source: https://habr.com/ru/post/1201380/


All Articles