2010-10-10 13 views
17

Mi chiedo quali differenze quali svantaggi e/o vantaggi ci sono a dichiarare un NSString questo modo:stringWithFormat vs. initWithFormat su NSString

NSString *noInit = [NSString stringWithFormat:@"lolcatz %d", i]; 

in contrapposizione a:

NSString *withInit = [[NSString alloc] initWithFormat:@"Hai %d", i]; 

Ciò che era la motivazione di mettere stringWithFormat invece di avere solo il modo initWithFormat di inizializzare la stringa?

risposta

33

stringWithFormat: restituisce una stringa autorizzata; initWithFormat: restituisce una stringa che deve essere rilasciata dal chiamante. Il primo è un cosiddetto metodo di "convenienza" che è utile per stringhe di breve durata, quindi il chiamante non deve ricordare di chiamare release.

+0

Ok, grazie ha senso. –

+1

Picchiato al pugno di 32 secondi. :-) –

+2

In realtà; è il '+ alloc' che restituisce l'istanza mantenuta ... il' init * 'non cambia il conteggio dei ritiri (ma potrebbe - in questo caso - restituire un'istanza diversa da quella che era stata chiamata). – bbum

3

Mi sono imbattuto in this blog nell'ottimizzazione della memoria proprio ieri. In esso, l'autore fornisce ragioni specifiche per cui sceglie di utilizzare [[NSString alloc] initWithFormat:@"..."] anziché [NSString stringWithFormat:@"..."]. In particolare, i dispositivi iOS potrebbero non rilasciare automaticamente il pool di memoria non appena lo si preferisce se si crea un oggetto autorelease.

La versione precedente richiede che si manualmente release esso, in un costrutto come questo:

NSString *remainingStr = nil; 
if (remaining > 1) 
    remainingStr = [[NSString alloc] initWithFormat:@"You have %d left to go!", remaining]; 
else if (remaining == 1) 
    remainingStr = [[NSString alloc] initWithString:@"You have 1 left to go!"]; 
else 
    remainingStr = [[NSString alloc] initWithString:@"You have them all!"]; 

NSString *msg = [NSString stringWithFormat:@"Level complete! %@", remainingStr]; 

[remainingStr release]; 

[self displayMessage:msg]; 

Qui, remainingStr era necessario solo temporaneamente, e in modo da evitare l'autorelease (che può accadere molto più tardi nel programma), gestisco esplicitamente la memoria come ne ho bisogno.

+1

È una scelta tra ottimizzazione prematura e codice chiaro conciso. Le ottimizzazioni premature possono essere risolte in seguito analizzando le prestazioni, il codice non chiaro è (solitamente) per sempre. – zaph

Problemi correlati