5

voglio variabile __block uso per ottenere il valore nel blocco. Ma quando fuori dal blocco, la variabile __block sembra essere nulla. Perché questo sarebbe successo?"__block" risultati variabili di valore nullo quando andare fuori del blocco

NSString *fileName = [Tools MD5Encode:url]; 
    __block NSString *filePath = nil; 
    [fileList enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { 
     NSString *aFileName = obj; 
     if ([aFileName isEqualToString:fileName]) { 
      NSString *path = [VERSIONS_INFO_DATA_DIRECTORY stringByAppendingPathComponent:aFileName]; 
      filePath = path; 
      NSLog(@"filePath1 %@", filePath); 
      *stop = YES; 
     } 
    }]; 
    //NSLog(@"filePath2 %@", filePath); 
    //filePath seems to be nil 
    return filePath; 

Quando cambio il codice in [copia percorso], funziona. Ma non ho idea se questa sia una buona idea. Qualche decisione?

NSString *fileName = [Tools MD5Encode:url]; 
    __block NSString *filePath = nil; 
    [fileList enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { 
     NSString *aFileName = obj; 
     if ([aFileName isEqualToString:fileName]) { 
      NSString *path = [VERSIONS_INFO_DATA_DIRECTORY stringByAppendingPathComponent:aFileName]; 
      filePath = [path copy]; 
      NSLog(@"filePath1 %@", filePath); 
      *stop = YES; 
     } 
    }]; 
    //NSLog(@"filePath2 %@", filePath); 
    return [filePath autorelease]; 
+1

è situazioni come questa che mi fa contento che il mio team ha deciso di abbracciare l'ARC. –

risposta

1

Va bene qui utilizzare la copia o conservare sul percorso. Il motivo per il vostro problema è che gli oggetti NSString sono membri degli oggetti convenienza insieme ad altri come NSArray che in realtà non hanno per rilasciare e sono stati già autoreleased dal sistema prima dei giorni di ARC. Personalmente, non mi piaceva che lo facessero solo perché causava confusione come questa. Poiché il blocco termina l'esecuzione del sistema, autorizza automaticamente l'oggetto stringa assegnato che causa la perdita.

5

http://www.mikeash.com/pyblog/friday-qa-2011-09-30-automatic-reference-counting.html

particolare:

Senza ARC, __block ha anche l'effetto collaterale di non trattenere il suo contenuto quando è catturato da un blocco. I blocchi si mantengono automaticamente e rilasciare tutti i puntatori di oggetti che catturano, ma i puntatori __block sono speciali prima lettera maiuscola e di agire come un puntatore debole. È diventato un modello comune fare affidamento su questo comportamento utilizzando __block per evitare i cicli di conservazione.

Sotto ARC, __block ora mantiene il suo contenuto, proprio come altri puntatori oggetti catturati. Il codice che utilizza __block per evitare i cicli di conservazione non funzionerà più. Invece, usa __weak come descritto sopra.

Quindi è necessario copiare.

+0

Non credo che "NSString * path = [VERSIONS_INFO_DATA_DIRECTORY stringByAppendingPathComponent: aFileName] è un oggetto stack allocato" è corretta. A quanto ho capito, solo l'oggetto blocco stesso (non tutti gli oggetti creati dal codice all'interno del blocco) è un oggetto stack. http://www.friday.com/bbum/2009/08/29/blocks-tips-tricks/ –

+0

Hai ragione ... grazie per la correzione di me. Modificherò il mio post. –

1

È l'uso di blocchi anche un problema qui?

mi sembra che questa sequenza di codice:

NSString *filePath = nil; 
NSString *path = [VERSIONS_INFO_DATA_DIRECTORY stringByAppendingPathComponent:aFileName]; 
filePath = path; 
return [filePath autorelease]; 

è over-rilascio filePath (perché non si possiede il risultato di -stringByAppendingPathComponent:, non dovrebbe essere (auto) rilasciandolo)

+0

bene, ho copiato il codice sbagliato. Quando uso "filePath = percorso", dovrebbe restituire filePath. Quindi, il problema è venuto. L'ho corretto ora. – Wayne

Problemi correlati