2010-03-21 9 views
7

Sto usando C structs in objc e ho creato una funzione che assembla la struttura come quella dell'API Cocoa. Il fatto è che questa struttura non è come NSRect o NSPoint questa struttura racchiude oggetti objc, quindi vedo una potenziale perdita di memoria qui. Devo fornire una funzione per "rilasciare" la struttura?Uso di C Structs che contiene oggetti ObjC?

Non sto creando una classe ISKNewsCategory perché non ci saranno comportamenti ma Pensi che questo sia un buon approccio o dovrei definire la classe anche se non ci sarà alcun comportamento?

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; 
} 

risposta

8

In generale, sarebbe molto meglio creare una classe contenitore semplice. In questo modo tutta la gestione della memoria è semplice e puoi utilizzare l'oggetto nelle classi standard del contenitore Cocoa senza dover ruotare attorno alla struttura in uno NSValue o altro.

L'unica volta che potrebbe essere accettabile utilizzare una struct in questo modo è se si dispone di un codice estremamente performante in cui il sovraccarico dell'oggetto potrebbe diventare un problema.

@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

Per espandere la "sola volta": iterare le strutture è 2-4 volte più veloce delle classi iteranti. Man mano che i progetti diventano più grandi, questo sta diventando un problema reale (il progetto corrente sta ripetendo molte centinaia di migliaia di articoli frequentemente, deve essere eseguito in tempo reale). – Adam

2

Qualsiasi cosa si ritenga, è necessario rilasciare. Tuttavia, non c'è nulla che dice che devi tenerli. Se la struttura è "proprietaria" degli oggetti, allora sì, dovresti conservarli e quindi devi rilasciarli. Se gli oggetti vengono mantenuti altrove, tuttavia, è possibile prendere in considerazione riferimenti deboli in cui non si mantengono gli oggetti.

2

Detesto creare classi senza alcun comportamento. :/Questo è un aspetto triste di Objective-C: le classi sono prolisse.

È necessario ricordare che le strutture in C vengono copiate ogni volta che vengono passate in giro. Pertanto, se le tue strutture conservano i loro oggetti e li dai a qualcun altro, si finisce automaticamente con un conteggio di riferimento errato per gli oggetti in esso contenuti.

Se pensate di passare intorno ai vostri oggetti, penso che dovreste renderlo una classe a tutti gli effetti. Se non lo fai, una struttura semplice andrà bene.

A causa della necessità di un "distruttore", dovresti averne uno. Dovresti sempre averne uno se c'è una pulizia da fare per la tua struttura.

+0

in realtà, la copia non causerà alcun ulteriore ritocco oltre al passaggio diretto di un oggetto, poiché viene copiato solo il puntatore. – cobbal

+0

@cobbal: questo è ciò che intendevo. Se passi la tua struttura, i puntatori agli oggetti verranno copiati e, se intendi mantenerli per ogni struttura in cui vivono, non puoi farlo. – zneak

0

Spero che questa soluzione ti sia utile.

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; 
}