2010-03-21 8 views
7

Ich benutze C-Strukturen in Objc und ich habe eine Funktion erstellt, die die Struktur wie die aus der Cocoa API zusammenbaut. Die Dinge sind, dass diese Struktur nicht wie NSRect ist o NSPoint diese Struktur packt objc Objekte soo Ich sehe ein potenzielles Speicherleck hier. Muss ich eine Funktion bereitstellen, um die Struktur freizugeben?Verwenden von C-Strukturen, die ObjC-Objekte enthalten?

Ich habe keine ISKNewsCategory-Klasse erstellt, weil es kein Verhalten geben wird. Denken Sie, dass dies ein guter Ansatz ist oder sollte ich die Klasse definieren, obwohl es kein Verhalten geben wird?

typedef struct ISK_NewsCategory { 
    NSString *name; 
    NSString *code 
} ISKNewsCategory; 

NS_INLINE ISKNewsCategory ISKMakeNewsCategory(NSString *name, NSString *code) { 
    ISKNewsCategory category; 
    category.name = [name retain]; 
    category.code = [code retain]; 
    return category; 
} 

Antwort

8

Im Allgemeinen wäre es viel besser, eine einfache Container-Klasse zu erstellen. Auf diese Weise ist die gesamte Speicherverwaltung einfach und Sie können das Objekt in den standardmäßigen Cocoa-Containerklassen verwenden, ohne die Struktur in einem NSValue oder was auch immer zu verwischen.

Die einzige Zeit, die es akzeptabel sein kann, eine Struktur auf diese Weise zu verwenden, ist, wenn Sie extrem leistungskritischen Code haben, bei dem der Objekt-Overhead zu einem Problem werden könnte.

@interface ISKNewsCategory : NSObject 
{ 
    NSString *name; 
    NSString *code; 
} 
@property (copy) NSString *name; 
@property (copy) NSString *code; 
@end 

@implementation ISKNewsCategory 
@synthesize name,code; 
- (void)dealloc 
{ 
    self.name = nil; 
    self.code = nil; 
    [super dealloc]; 
} 
@end 
+1

Um Ihre "einzige Zeit" zu erweitern: iterierende Strukturen ist 2-4x schneller als iterierende Klassen. Wenn Projekte größer werden, wird dies zu einem echten Problem (das aktuelle Projekt iteriert häufig viele Hunderttausende von Elementen, muss in Echtzeit ausgeführt werden). – Adam

2

Alles, was Sie behalten, müssen Sie freigeben. Es gibt jedoch nichts, was besagt, dass Sie sie behalten müssen. Wenn die Struktur die Objekte "besitzt", dann sollten Sie sie behalten, und dann müssen Sie sie freigeben. Wenn die Objekte an anderer Stelle jedoch beibehalten werden, sollten Sie schwache Referenzen berücksichtigen, bei denen Sie die Objekte nicht beibehalten.

2

Ich hasse es, Klassen auch ohne Verhalten zu erstellen. : Dies ist ein trauriger Aspekt von Objective-C: Klassen sind ausführlich.

Sie müssen daran denken, dass Strukturen in C jedes Mal kopiert werden, wenn sie herumgereicht werden. Wenn Ihre Strukturen ihre Objekte behalten und Sie sie einer anderen Person übergeben, erhalten Sie automatisch eine fehlerhafte Referenzzahl für die darin enthaltenen Objekte.

Wenn Sie vorhaben, Ihre Objekte überhaupt zu passieren, sollten Sie sie zu einer vollwertigen Klasse machen. Wenn Sie dies nicht tun, ist eine einfache Struktur in Ordnung.

Aus der Notwendigkeit eines "Destruktors" sollten Sie einen haben. Sie sollten immer eine haben, wenn es eine Bereinigung für Ihre Struktur geben soll.

+0

tatsächlich wird das Kopieren nicht dazu führen, dass mehr als nur ein Objekt übergeben wird, da nur der Zeiger kopiert wird. – cobbal

+0

@cobbal: das ist was ich meinte. Wenn Sie Ihre Struktur übergeben, werden die Zeiger auf die Objekte kopiert, und wenn Sie sie für jede Struktur beibehalten möchten, in der sie leben, können Sie das nicht einfach tun. – zneak

0

Ich hoffe, dass diese Lösung für Sie hilfreich sein wird.

typedef struct ISK_NewsCategory { 
    NSString *name; 
    NSString *code; 
} ISKNewsCategory; 

NS_INLINE ISKNewsCategory ISKMakeNewsCategory(NSString *inName, NSString *inCode) { 

    ISKNewsCategory category; 

    [category.name autorelease]; 
    category.name = [inName retain]; 

    [category.code autorelease]; 
    category.code = [inCode retain]; 

    return category; 
} 
Verwandte Themen