0

Ich bin gespannt, ob es möglich ist, __block Objekte innerhalb von asynchronen Blöcken in MRC und ARC einfach zuzuweisen und zu behalten. Ich habe den folgenden Code erhalten, während ich ein Stück Code mit minimalen Änderungen neu geschrieben habe. Ich blieb stecken, als ich versuchte, das Bild von einem asynchronen Block zurückzugeben. Eine Sorge ist, dass der Code eines Tages in ARC konvertiert werden würde. Ich möchte nach der Konvertierung keinen versteckten Speicherabsturz haben. Meine Optionen warenObjekte Variablen außerhalb von asynchronen Blöcken zuweisen

  1. ein GCD Objekthalter verwenden, wenn eine solche Sache
  2. existiert
  3. ein homebrew Objekthalter verwenden, ein Array oder andere
  4. direkt hinzufügen das Bild auf das Array (die ich verwende)
  5. Umschreiben des Codes an eine andere Struktur

Grundsätzlich sind die Codelade mehrere Bilder in einem Hintergrund-Thread. Suche // image deallocated :( gibt Ihnen den Standort.

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 

    ALAssetsLibrary *assetsLibrary = nil; 
    for (int i = 0; i < sources.count; ++i) { 

     __block UIImage *image = nil; 
     id source = sources[i]; 

     if ([source isKindOfClass:[NSString class]]) { 

      image = something 

     } else if ([source isKindOfClass:[NSURL class]]) { 

      NSURL *url = source; 

      if ([url.scheme isEqualToString:@"assets-library"]) { 

       dispatch_group_t group = dispatch_group_create(); 

       if (!assetsLibrary) 
        assetsLibrary = [[[ALAssetsLibrary alloc] init] autorelease]; 

       dispatch_group_enter(group); 
       [assetsLibrary assetForURL:url resultBlock:^(ALAsset *asset) { 

        image = something 
        dispatch_group_leave(group); 

       } failureBlock:^(NSError *error) { 

        dispatch_group_leave(group); 

       }]; 

       dispatch_group_wait(group, DISPATCH_TIME_FOREVER); 

       // image deallocated :(

      } else if (url.isFileURL) { 

       image = something 

      } 
     } 
     // add image to an array 
    } 

    dispatch_async(dispatch_get_main_queue(), ^{ 

     // notify 

    }); 
}); 

Antwort

0

Ich denke, das Verschieben der Bildvariablendeklaration wäre der erste richtige Schritt, um darüber nachzudenken. Sie können nicht erwarten, eine Bildvariable für mehrere gleichzeitige Operationen zu haben.

so zu beginnen, lassen Sie uns Danach this-

ALAssetsLibrary *assetsLibrary = nil; 
for (int i = 0; i < sources.count; ++i) { 
__block UIImage *image = nil; 

tun, halten Sie derzeit UIImage Instanzen in einem Array? Dies wird nicht empfohlen. Bitte finden Sie eine Möglichkeit, diese Bilder in das Dokumentenverzeichnis zu schreiben und später bei Bedarf von dort zu lesen. Das Speichern von UIImage-Instanzen im Speicher führt zu schwerwiegenden Problemen bei der Speicherüberlastung.

Sie müssen sich eine Namenskonvention ausdenken, um Ihre Bilder in das Dokumentenverzeichnis zu schreiben. Wann immer ein Bild geladen wird, speichern Sie es einfach in Ihrem lokalen Ordner und lesen Sie später von dort.

Sie können auch den Benachrichtigungsteil aufrufen, sobald ein Bild geladen ist, und sich über andere informieren, wenn Sie sie erhalten. Nicht sicher, wie Ihr Design funktioniert.

Außerdem habe ich festgestellt, dass Sie mehrere Gruppen erstellen. Eine neue Gruppe mit jeder Iteration innerhalb for Schleife hier-

dispatch_group_t group = dispatch_group_create(); 

es außerhalb for Schleife bewegen wäre ein guter Ruf sein.

Hoffe, das hilft.

+0

Die Operation innerhalb der Schleife ist seriell. Die Position der Bildvariablen ist falsch, weil ich sie nach dem Bearbeiten an die falsche Stelle gesetzt habe. Der ganze Zweck des Codes besteht darin, Bilder in den Speicher zu laden. – keithyip

+0

@keithyip Wie viele Bilder sprechen wir maximal an? –

+0

@keithyip Sollten Sie nicht verschieben ** dispatch_group_t group = dispatch_group_create(); ** außerhalb der for-Schleife? –

Verwandte Themen