2009-09-28 8 views
8

EDIT_v002

Ho dato un'occhiata a tutti i commenti e sto iniziando a vedere cosa dovrei fare. A tal fine ho modificato il mio codice (vedi sotto) Ho cambiato newPath in una NSString, rimosso [[alloc] init] e la fine [release] come ora gestita dal sistema. Sto usando stringByAppendingPathComponent, permettendogli di aggiungere un separatore tra rootPath e fileName prima di essere assegnato a NSString. Funziona e l'ho eseguito attraverso l'analizzatore statico senza problemi.stringByAppendingPathComponent, come funziona?

// ------------------------------------------------------------------- ** 
// DISC: FILEWALKER ..... (cocoa_fileWalker.m) 
// DESC: List all "*.png" files in specified directory 
// ------------------------------------------------------------------- ** 
#import <Foundation/Foundation.h> 

int main (int argc, const char * argv[]) { 
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; 

    NSString *fileName; 
    NSDictionary *attrDir; 
    NSError *myError; 
    NSNumber *fileSize; 
    NSFileManager *manager = [NSFileManager defaultManager]; 
    NSString *rootPath = [@"~/Pictures/Ren/PRMan" stringByExpandingTildeInPath]; 
    NSString *newPath; 

    NSLog(@"Home: %@",rootPath); 

    for(fileName in [manager enumeratorAtPath:rootPath]){ 
     if ([[fileName pathExtension] isEqual:@"png"]) {  

      newPath = [rootPath stringByAppendingPathComponent:fileName]; 
      attrDir = [manager attributesOfItemAtPath:newPath error:&myError]; 
      fileSize = [attrDir objectForKey: @"NSFileSize"]; 
      NSLog(@"File: %@ Size: %@", newPath, fileSize); 
     } 
    } 
    [pool drain]; 
    return 0; 
} 
// ------------------------------------------------------------------- ** 

Gary

risposta

15

stringByAppendingPathComponent, Hows funziona?

semplice. Si desidera aggiungere un componente di percorso. Si invia il messaggio alla stringa si desidera aggiungere un componente di percorso, passando il percorso componente che si vuole accodare

componenti del percorso non sono i tagli,. se lo fossero, il metodo pathComponents sarebbe tornato altro che una serie di barre componenti del percorso sono le parti tra le barre (anche se c'è un caso speciale. , descritto nel defi nizione di pathComponents).

La barra è il percorso separatore. Questo è hard-coded all'interno di Cocoa; è attualmente (e probabilmente sarà sempre) una barra. Quindi, se davvero volessi aggiungere una barra a una stringa, il motivo più probabile sarebbe che tu voglia aggiungere un percorso separatore, non un percorso componente.

[newPath setString:rootPath]; 
    [newPath appendString:@"/"]; 
    [newPath appendString:fileName]; 

fileName è il componente che si desidera aggiungere. Utilizzare stringByAppendingPathComponent: e passare fileName, non una barra.

Per quanto riguarda l'eventuale perdita di dati: un oggetto non rientra nello scope senza essere rilasciato? La risposta a questa domanda è la risposta a se è una perdita. Se non sei sicuro, consulta the memory management rules.

+0

Quindi in sostanza si forniscono i componenti del percorso e stringByAppendingPathComponent aggiunge il separatore? Inoltre non riesco a vedere come dici che non funziona, sul mio sistema elenca tutte e 4 le immagini EXR nel percorso. Fondamentalmente newPath viene prima assegnato, quindi viene semplicemente reimpostato e ricostruito ogni volta intorno al ciclo, ottenendo infine il rilascio alla fine. – fuzzygoat

+0

Sì. Normalmente si fornisce solo un componente di percorso, ma un sottotracciato funziona altrettanto bene. –

+0

Inoltre: hai ragione su 'newPath'. Scusa per la confusione su questo; Non ho visto il tuo messaggio 'setString:'. Ho eliminato il paragrafo, poiché non si applica al codice nella versione corrente della tua domanda. –

0
[testPath stringByAppendingString:@"/"] 
4

Tu non aggiungere il delimitatore. Si aggiunge il componente del percorso successivo (ad esempio nomefile, dir, ecc.). Questo evita di dover conoscere il delimitatore per il tuo particolare sistema.

NSMutableString* mutablePath = [NSMutableString string]; 
NSString* fullPath = [rootPath stringByAppendingPathComponent:filename]; 

[mutablePath setString:fullPath]; // OK to setString: of Mutable with non-Mutable 
[mutablePath appendString:someOtherString]; // This won't cause an exception 

// Example to clarify on comments below 
{ 
    // This will cause a compiler warning. 
    // warning: incompatible Objective-C types assigning 
    // ‘struct NSString *’, expected ‘struct NSMutableString *’ 
    NSMutableString* ms = [@"FOO" stringByAppendingPathComponent:@"BAR"]; 
} 

C'è abbastanza chiaro esempio in the documentation.

+0

[testPath setString: [@ "TEST_" stringByAppendingPathComponent: @ "/"]]; solo curioso, testPath è NSMutableString, funziona in questa situazione? – fuzzygoat

+0

Sì. Funziona bene – nall

+0

solo curioso, se qualcosa restituisce un NSString e lo si assegna a un NSMutableString, presumevo che fosse ok? – fuzzygoat

1

L'ultima riga dovrebbe essere:

testPath = [testPath stringByAppendingPathComponent:@"/"]; 
+1

Ciò trasformerebbe 'testPath' in un' NSString' quando è stato dichiarato e allocato come una stringa mutabile. – dreamlax

+1

Inoltre, la stringa originale 'testPath' è ora trapelata, poiché non era autorizzata. – dreamlax

2

-stringByAppendingPathComponent restituisce una nuova stringa immutabile, non modifica l'originale. Devi usare il valore di ritorno di questo metodo.

5

Tutte le risposte esistenti perdono la stringa originale testPath. Per qualcosa di così semplice, perché nessuno ha consigliato di immettere -[NSMutableString appendString:]?

[testPath appendString:@"/"]; 

Non c'è equivalente a -stringByAppendingPathComponent: per NSMutableString, ma sembra che stia solo cercando di aggiungere una barra, non un componente del percorso in ogni caso. Se davvero si voleva aggiungere un componente di tracciato, si potrebbe fare questo:

[testPath setString:[testPath stringByAppendingPathComponent:@"..."]]; 

E 'una soluzione fastidioso, ma come @dreamlax sottolinea, -stringByAppendingPathComponent: restituisce sempre una stringa immutabile, anche quando viene chiamato su un oggetto NSMutableString. :-(

+0

NSMutableString * è * un NSString e quindi ha stringByAppendingPathComponent. – nall

+3

Lo capisco, ma restituisce comunque una nuova stringa autorizzata, piuttosto che modificare il contenuto della stringa mutabile, come ci si aspetterebbe se ci fosse un metodo chiamato "-appendPathComponent:". –

+3

Sembra che questo sia il modo più semplice per ottenere ciò che il richiedente originale desiderava e il risultato è ancora una NSMutableString. – alesplin