2012-06-19 15 views
5

ho scritto il seguente codice di esempio per vedere come funziona ARCPerché le proprietà NSString deboli non vengono rilasciate in iOS?

@property (nonatomic, weak) NSString *myString; 
@property (nonatomic, weak) NSObject *myObj; 
@end 

@implementation ViewController 
@synthesize myString = _myString; 
@synthesize myObj = _myObj; 
- (void) viewDidAppear:(BOOL)animated 
{ 
    NSLog(@"Appearing Obj: !%@!",self.myObj); 
    NSLog(@"Appearing String: !%@!",self.myString); 
} 

- (void)viewDidLoad 
{ 
    self.myObj = [[NSObject alloc] init]; 
    self.myString = [[NSString alloc] init]; 
    NSLog(@"Loading Obj %@",self.myObj); 
    NSLog(@"Loading String: !%@!",self.myString); 
} 

Tuttavia sorprendentemente ho ottenuto questi risultati:

2012-06-19 15:08:22.516 TESTER[4041:f803] Loading Obj (null) 
2012-06-19 15:08:22.517 TESTER[4041:f803] Loading String: !! 
2012-06-19 15:08:22.533 TESTER[4041:f803] Appearing Obj: !(null)! 
2012-06-19 15:08:22.535 TESTER[4041:f803] Appearing String: !! 

Come si può vedere, Obj stato rilasciato correttamente, ma la mia stringa (che è anche una proprietà debole) non stampa nulla ... Perché no?

+0

È la stringa che si sta impostando in 'myString' con qualsiasi modifica di una stringa letterale (qualcosa come @" Hello world! ")? –

risposta

12

NSString utilizza tutti i tipi di trucchi interni per riutilizzare gli oggetti ed evitare allocazioni e copie non necessarie. Può farlo perché le istanze di NSString sono immutabili. In questo caso è probabile che un'istanza condivisa rappresenti una stringa vuota che viene restituita da [[NSString alloc] init] e questa istanza condivisa verrà conservata da qualche altra parte come singleton.

+0

Questo sembra avere un senso. Grazie! – Nosrettap

+0

Forse qualcuno può controllare il codice sorgente NSString per confermare questo. –

+0

Ha senso, anche se non penserei che sarebbe saggio fare affidamento su questo comportamento, che sembra essere solo una manifestazione di qualche ottimizzazione, che è soggetta a modifiche in una data futura. – Rob

6

[[NSString alloc] init] restituisce sempre il valore identico. Puoi controllarlo da solo.

NSString *string1 = [[NSString alloc] init]; 
NSString *string2 = [[NSString alloc] init]; 
NSString *string3 = [[NSString alloc] init]; 
NSLog(@"string1 = %p, string2 = %p, string3 = %p", string1, string2, string3) 

Questo codice restituisce tre indirizzi identici. Nel mio caso, l'uscita era:

string1 = 0x3e8dd74c, string2 = 0x3e8dd74c, string3 = 0x3e8dd74c 

Ciò significa [[NSString alloc] init] rendimenti Singleton. Solitamente i single non possono essere rilasciati.

fare le stringhe con altri metodi (come initWithFormat:) rende soliti 'non Singleton' oggetti, che di solito può essere rilasciato, con alcune eccezioni.

Ulteriori: Guardando il codice sorgente (Assembler):

-[NSPlaceholderString init]: 
00040ea4  f64b009c  movw r0, 0xb89c 
00040ea8  f2c00016  movt r0, 0x16 
00040eac   4478  add  r0, pc 
00040eae   4770  bx  lr 

sarebbe qualcosa di simile (in ObjectiveC)

-(id)init 
{ 
    return SOME_CONSTANT_VALUE; 
} 

Potrebbe essere kCFEmptyString, ma non sono sicuro.

Problemi correlati