2010-10-11 10 views
31

Ich entwickle eine Anwendung, die etwa 100 Bilder oder mehr erfordert, die zusammen mit anderen verwandten Informationen in die Core Data-Datenbank eingefügt werden.Wie soll ich UIImagages in meiner Core Data-Datenbank speichern?

Jetzt kann ich einfach andere Daten hinzufügen, indem ich nur ein paar Zeilen Code schreibe, aber für UIImagages bin ich mir nicht sicher, wie ich das machen soll, ohne viel Code zu schreiben. Ich habe mich gefragt: Gibt es das überhaupt, um das leicht zu machen, oder wenn es nicht den besten Weg gibt, dies mit der geringsten Anstrengung zu erreichen?

Auch ist es in Ordnung, Bilder in einer Core Data-Datenbank zu speichern oder sollten wir nur die Adressen von Bildern auf dem lokalen Dateisystem speichern?

Antwort

55

Das Speichern von Bildern in einer Core Data-Datenbank ist ziemlich einfach. Sie müssen nur Ihr Bildattribut als transformierbar markieren und eine Unterklasse von NSValueTransformer erstellen. Innerhalb dieser Unterklasse, fügen Sie Code wie folgt aus:

+ (Class)transformedValueClass 
{ 
    return [NSData class]; 
} 

+ (BOOL)allowsReverseTransformation 
{ 
    return YES; 
} 

- (id)transformedValue:(id)value 
{ 
    if (value == nil) 
     return nil; 

    // I pass in raw data when generating the image, save that directly to the database 
    if ([value isKindOfClass:[NSData class]]) 
     return value; 

    return UIImagePNGRepresentation((UIImage *)value); 
} 

- (id)reverseTransformedValue:(id)value 
{ 
    return [UIImage imageWithData:(NSData *)value]; 
} 

Für Ihre wandelbare Attribut geben Sie den Namen dieser Unterklasse als Wert Transformator Namen.

Sie können dann eine NSManagedObject Unterklasse für die Einheit der Ausrichtung dieses Bild Attributs erstellen und eine Eigenschaft für dieses Bild Attribut deklarieren:

@property(nonatomic, retain) UIImage *thumbnailImage; 

Sie UIImages aus und schreibt UIImages diese Eigenschaft lesen kann und sie werden transparent sein geändert zu und von NSData, um in der Datenbank gespeichert zu werden.

Ob Sie dies tun, hängt von Ihrem speziellen Fall ab. Größere Bilder sollten wahrscheinlich nicht auf diese Weise gespeichert werden oder zumindest in ihrer eigenen Entität sein, so dass sie nicht in den Speicher geholt werden, bis eine Beziehung zu ihnen folgt. Kleine Thumbnail-Bilder sind wahrscheinlich in dieser Weise in Ihrer Datenbank zu speichern.

+51

Nur ein Follow-up für jeden, der dies jetzt überprüft: UIImage entspricht jetzt NSCoding in iOS 5. Wenn Sie in der Lage sind, iOS 5 und höher zu zielen, können Sie einfach das Attribut und Transformable setzen und fertig sein. Sie können auch "Erlaube externen Speicher" aktivieren, um zu bewirken, dass größere Bilder automatisch außerhalb Ihres Core Data-Speichers gespeichert werden. – atticus

+0

Der Code, der automatisch von CoreData generiert wird, hat eine ID anstelle von UIImiage * als Attribut. Ist das normal? Sollen wir das ändern? –

+1

@JimThio - Richtig, das ist die Standardeinstellung. Da ich weiß, dass ich dieser transformierten Eigenschaft ein UImage zuweisen werde, ändere ich den Typ in UIImage. Dies hilft, meinen Code klar zu halten, und bietet eine Plausibilitätsprüfung, wenn ich versuche, diese Eigenschaft falsch zu verwenden. –

8

von Apple hat einige Ratschläge um BLOBs bieten: Large Data Objects (BLOBs)

Wenn Ihre Anwendung großen BLOBs ("Binary Large Objects" wie Bild und Tondaten), müssen Sie kümmern zu minimieren Gemeinkosten. Die genaue Definition von "klein", "bescheiden" und "groß" ist fließend und hängt von einer Anwendung ab. Eine lose Regel von Daumen ist, dass Objekte in der Größenordnung von Kilobyte Größe sind von einer "bescheidenen" Größe und die in der Größenordnung von Megabyte Größe sind "groß". Einige Entwickler haben eine gute Leistung mit 10 MB BLOBs in einer Datenbank erreicht. Wenn andererseits eine Anwendung Millionen von Zeilen in einer Tabelle hat, können sogar 128 Bytes ein "bescheidener" Größe CLOB (Character Large OBject) sein, der in eine separate Tabelle normalisiert werden muss .

Wenn Sie BLOBs in einem permanenten Speicher speichern müssen, sollten Sie im Allgemeinen einen SQLite-Speicher verwenden.Die XML und binäre speichert verlangen, dass das gesamte Objekt Graph in Speicher, und speichern schreibt atomar sind (siehe „Persistent Speicher Eigenschaften“), was bedeutet, dass sie beschäftigen großen Datenobjekte nicht effizient zu tun. SQLite kann auf skalieren extrem große Datenbanken verarbeiten. Richtig eingesetzt, SQLite bietet gute Leistung für Datenbanken bis zu 100 GB, und eine einzelnen Zeile kann bis zu 1 GB hält (obwohl natürlich 1 GB Daten in dem Speicher zu lesen ist ein teurer Betrieb unabhängig davon, wie effizient das Repository) .

Ein BLOB stellt oft ein Attribut eines Unternehmens, zum Beispiel ein Foto könnte ein Attribut eines Mitarbeiters Einheit sein. Für kleine bis mittelgroße BLOBs (und CLOBs) sollten Sie eine separate Entität für die Daten und erstellen, um eine eindeutige Beziehung des Attributs zu erstellen. Zum Beispiel, Sie könnten Mitarbeiter erstellen und Entitäten mit einer Eins-zu-Eins- Beziehung zwischen ihnen fotografieren, wo die Beziehung von Mitarbeitern zu Fotografie, die das Foto Attribut Employee ersetzt. Dieses Muster maximiert die Vorteile des Objekts Fehler (siehe "Fehlgeschlagen und Uniquing"). Jedes gegebene Foto wird nur abgerufen, wenn es tatsächlich benötigt wird (wenn die Beziehung durchlaufen wird).

Es ist jedoch besser, wenn Sie in der Lage sind BLOBs zu speichern, wie Ressourcen auf dem Dateisystem und Links zu pflegen (wie URLs oder Pfade) auf diese Ressourcen. Sie können dann ein BLOB als und bei Bedarf laden.

11

Ein gutes Beispiel für den Bildwandler wie oben beschrieben ist in der iPhoneCoreDataRecipes-Demo-Anwendung.

+0

Ausgezeichnet! Danke für die Köpfe hoch! – Fogmeister

+1

Hier ist der aktuelle Link zum Beispiel: https://developer.apple.com/library/content/samplecode/iPhoneCoreDataRecipes/Einführung/Intro.html –

Verwandte Themen