2010-12-29 8 views
2

Ich habe eine App, die ich Refactoring bin und ich habe gerade Multithreading implementiert, so dass die Benutzeroberfläche reibungsloser laufen kann. Im Iphone Simulator bekomme ich keine Lecks, aber auf meinem iPhone 3G auf iOS 4.2 getestet bekomme ich ein Speicherleck. Ich habe viel nach dem richtigen Weg gesucht, um einen Autorespulepool mit einer Operationswarteschlange zu implementieren, Hilfe wird sehr geschätzt.Wie man Autorespeichepool für eine Nsoperationsqueue richtig verwendet

ich eine NSOperationQueue in meinem Viewcontroller als solche

- (void)loadData 
{ 
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 
    NSOperationQueue *queue = [NSOperationQueue new]; // creates multithread for loading data without slowing UI 
    NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(firstRun) object:nil]; 

    [queue addOperation:operation]; 
    [operation release]; 
    [queue release]; 
    [pool release]; 
} 

Antwort

0

Sie sollen ein NSAutoreleasePool zu Beginn des Verfahrens erstellen erstellt haben, die die NSOperation (in diesem Fall firstRun) berufen wird, und es an dem Drain Ende der Methode.

2

Zuerst sollten Sie nicht nur erstellen und dann die Warteschlange freigeben. Es ist natürlicher, diese Warteschlange als eine der Klassen Ihrer Klasse zu erstellen und sie dann zu veröffentlichen, wenn der View-Controller nicht mehr aktiv ist (Sie können auch ausstehende Operationen abbrechen und alle laufenden Operationen abbrechen/warten).

Zweitens benötigen Sie den Autorelease-Pool in der Methode, die die Operation erstellt und in der Warteschlange hinzufügt, seit diese Methode aus dem Hauptthread aufgerufen wird. Stattdessen benötigen Sie den Autorelease-Pool aus der Methode, die Ihr Objekt tatsächlich aufruft (dies könnte in einem anderen Thread ausgeführt werden).

Also, haben Sie vielleicht die folgende (vorausgesetzt, Sie Ihre Warteschlange Ivar warteschlange_ nennen):

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    if(!queue_) queue_ = [[NSOperationQueue alloc] init]; 
    // other view loading code 
} 

- (void)loadData 
{ 
    NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(firstRun) object:nil]; 
    [queue_ addOperation:operation]; 
    [operation release]; 
} 

- (void)firstRun 
{ 
    // Here we may run on another thread, so 1) we need an autorelease pool; and 
    // 2) we need to make sure we don't do anything that requires a runloop 
    NSAutoreleasePool* threadPool = [NSAutoreleasePool new]; 

    // do long-running things 

    [threadPool drain]; 
} 

- (void)dealloc 
{ 
    if(queue_) { 
    [queue_ setSuspended:YES]; 
    [queue_ cancelAllOperations]; 
    // you need to decide if you need to handle running operations 
    // reasonably, but don't wait here because that may block the 
    // main thread 
    [queue_ release]; 
    } 
    // other dealloc stuff 
    [super dealloc]; 
} 

Sie können auch Ihre Warteschlange auf Nachfrage, initialisieren so statt in viewDidLoad der Initialisierung überprüfen für seine Existenz und initialisieren Falls nötig, fügen Sie eine Operation hinzu. Dies könnte in einen eigenen Methodenaufruf eingebettet sein, aber eine lazy Initialisierung hier ist wahrscheinlich nicht wirklich notwendig, da Warteschlangen ziemlich leicht sind.

+0

danke Jason, werden irgendwelche Methoden nach dem threadpool init automatisch verwendet werden? Außerdem muss ich den Threadpool freigeben. Ich sehe, dass es mit neuem begonnen hat. – zambono

+0

@zambono: Ja, es sollte die erste Zeile sein und Sie sollten den Pool als letzte Zeile in Ihrer Methode entleeren. Die "neue" Methode ist nur eine Abkürzung für alloc/init, also ist [NSObject new] dasselbe wie [[NSObject alloc] init], also sind Sie dafür verantwortlich. Autorelease-Pools sind jedoch etwas Besonderes. Die Drain-Methode dort gibt auch den Pool frei, so dass Sie nicht eine bestimmte Release-Nachricht senden müssen (wenn Sie dies tun, ignoriert es es einfach). –

Verwandte Themen