2014-08-29 3 views
5

Ich bin ein Projekt auf iOS 7 unter Verwendung von ARC zu entwickeln, möchte ich eine Privateigentum lösen, wenn die Viewcontroller Hier
veröffentlicht wird, ist die TestViewController, die als eine modale Ansicht präsentiert wird Controller, einen Wert an die Privateigentum testAVPlayer in viewDidLoad Einstellung:Wie das Privateigentum in iOS veröffentlichen 7 ARC mit

//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 ist eine Unterklasse von AVPlayer, habe ich ein NSLog in die 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 

Wenn TestViewController entlassen wird, die testAVPlayer scheint nie, freigegeben ich die "dealloc TestViewController" zu sehen, aber es gibt keine "dealloc testAVPlayer" in Konsolenprotokoll

+0

Sie müssen nicht dealloc das ist der ganze Punkt von ARC ... – meda

+3

@meda ja, aber 'dealloc' sollte immer noch aufgerufen werden, wenn von ARC freigegeben. Irgendetwas muss das Objekt behalten, aber ich fürchte, es gibt nicht genug, um hier weiterzumachen. –

+0

Sie können es irgendwo im Block behalten oder wiederholenden Timer ohne Ungültigkeit verwenden. Es sind jetzt nicht genug Informationen. –

Antwort

10

ich Ihren Code versucht, das Problem ist, dass selbst wenn Sie [TestAVPlayer playerWithPlayerItem:item] die TestAVPlayer Klasse rufen nicht solche Methode hat, so ist es playerWithPlayerItem: Funktion aufrufen, wird von die Basisklasse, die eine Instanz der Klasse anstelle der Klasse TestAVPlayer zurückgibt. Der Compiler gibt Ihnen keine Warnung, da die Methode playerWithPlayerItem: den Typ id zurückgibt. Wenn Sie dies mit dem Debugger überprüfen werden Sie sehen, dass der private Variablentyp ist nicht TestAVPlayer:

enter image description here

Die dealloc des TestAVPlayer wird nie als solches Objekt aufgerufen werden, erstellt wurde. Die Instanz wird freigegeben, wenn die TestViewController freigegeben wird. Sie können dies überprüfen, indem Sie Instrumente verwenden oder einfach einen symbolischen Haltepunkt zu [AVPlayer dealloc] hinzufügen.

Wählen Sie den Breakpoint Navigator und klicken Sie auf die Schaltfläche + und fügen Sie einen symbolischen Breakpoint hinzu.

schreiben [AVPLayer dealloc] zum Symbol Feld ein und drücken Sie die Eingabetaste.Wenn Sie die Anwendung ausführen und die TestViewController freigegeben wird, dann werden Sie sehen, dass der Haltepunkt getroffen wird, daher die AVPlayer wirklich freigegeben wird.

2

testAVPlayer = [AVPlayer playerWithPlayerItem:playerItem];

Sie verwenden AVPlayer, nicht Ihre TestAVPlayer.

+0

BTW das sollte die richtige Antwort sein. :) Ich habe nicht bemerkt, dass AVPlayer anstelle von Unterklasse verwendet wird. –

+0

Ich habe meinen Code bearbeitet, den AVPlayer durch TestAVPlayer ersetzt, aber er kann immer noch nicht veröffentlicht werden. – bandw

+0

@bandw Haben Sie woanders auf 'testAVPlayer' zugegriffen? –

5

Sie verwenden eine Klassenfactory-Methode, um Ihr Objekt zu initialisieren, was bedeutet, dass Sie das testAVPlayer-Objekt nicht besitzen und daher nicht für die Freigabe verantwortlich sind.

Weitere Informationen finden Sie in der Dokumentation zu Concepts in Objective-C unter Class Factory Methods.

Wenn Sie in der Tat wollen die Lebensdauer dieses Objekts besitzen und zu steuern, verwenden Sie den folgenden initializer:

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

und Ihre dealloc Methode aufgerufen.

1

Versuchen - viewDidUnload dann nil der testAVPlayer Umsetzung:

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

Obwohl Sie es als [TestAVPlayer playerWithPlayerItem:item] anrufen, bekommen Sie wirklich eine Instanz von AVPlayer, nicht TestAVPlayer zurück. In der Tat wird die Instanz, die Sie erstellt haben, wirklich freigegeben. Das Dealloc-Protokoll wird nicht angezeigt, da eine Instanz dieser Klasse niemals erstellt wird.

Wie von einem anderen vorgeschlagen, ersetzen [TestAVPlayer playerWithPlayerItem:item] durch [[TestAVPlayer alloc] initWithPlayerItem:item]; und Sie sollten beginnen, Ihre Protokolle zu sehen.

Verwandte Themen