Domanda

Pensavo che una variabile in obiettivo-c fosse solo un riferimento a un oggetto da qualche parte nella memoria. Quindi per la mia comprensione, il risultato deve essere stato "uno", perché alla fine ho assegnato l'indirizzo di memoria dell'oggetto di str1 a str2, e in precedenza avevo assegnato l'indirizzo di memoria di str2 per testare.

NSString *str1 = [NSString stringWithCString:"one"];
NSString *str2 = [NSString stringWithCString:"two"];

test = str2; // test is an instance variable. I use no getter/setter here! just for testing!
str2 = str1;
NSLog(test); // = "two" ??
È stato utile?

Soluzione

Ecco come funzionano i puntatori. Il risultato che vedi è normale e corretto.

Elenca tutte le tue variabili e quali stringhe indicano in memoria quando vengono dichiarate:

str1 -> "One"
str2 -> "Two"

Quindi, esegui alcune istruzioni di assegnazione:

test = str2;

Questo assegna il valore del puntatore str2 a test . Quindi i puntatori sono

str1 -> "One"
str2 -> "Two"
test -> "Two"

Poi

str2 = str1;

Assegna il valore del puntatore str1 a str2 . Ora i puntatori sono

str1 -> "One"
str2 -> "One"
test -> "Two"

Quindi stampi test , che punta a ciò che str2 puntava originariamente, che è " Due " ;.

Penso che tu pensi che da quando hai assegnato str2 al valore di str1 e test al valore di str2 , che il valore di str1 si trasforma in qualche modo in test . Questo non è il caso. Una volta assegnato il valore di test , le informazioni relative alla provenienza di tale valore vengono perse. Se vuoi che il valore di test sia lo stesso di str1 , devi invertire l'ordine delle tue operazioni di assegnazione:

str2 = str1;
test = str2;

Altri suggerimenti

Hai questo:

test = str2; // test is an instance variable.testing!
str2 = str1;
NSLog(test); // = "two" ??

Ora, facciamo finta che tutte quelle variabili fossero ints.

Nella prima riga, la variabile test è impostata sul valore della variabile str2 . Sulla seconda riga, la variabile str2 è impostata sul valore della variabile str1 . Sulla terza riga, stampiamo il valore di test , ed è effettivamente il valore che str2 era quando assegnammo str2 al test. Non importa affatto che successivamente abbiamo assegnato a str2 un valore diverso.

Ok, ma le variabili sono in realtà puntatori, dici, non ints.

Non importa: pensa a un puntatore come a un numero, l'indirizzo di un punto della memoria. E passandolo a NSLog, NSLog non stampa il valore del puntatore, ma il valore di ciò a cui punta il puntatore, che è un array di caratteri.

Una variabile è un contenitore. Il compito prende tutto ciò che è dalla parte di destra e lo mette anche in qualunque cosa dalla parte di sinistra. In altre parole, copia il valore da una variabile all'altra; in questo caso, quei valori sono puntatori (indirizzi di memoria).

Quindi, ecco cosa hai fatto:

  1. Prendi l'indirizzo che si trova nella variabile str2 e inserisci lo stesso indirizzo nella variabile test .
  2. Prendi l'indirizzo che si trova nella variabile str1 e inserisci lo stesso indirizzo nella variabile str2 .

Il passaggio 2 non influisce sulla variabile test ; l'unica assegnazione a quella variabile è stata nel passaggio 1.

Importante: non stai copiando cosa c'è nell'indirizzo; stai copiando l'indirizzo stesso . C'è ancora solo un & # 8220; due & # 8221; stringa, ma tra i passaggi 1 e 2, l'indirizzo di quell'oggetto si trova sia in str2 che in test . Quindi, al passaggio 2, sostituisci l'indirizzo in str2 con l'indirizzo di & # 8220; one & # 8221; stringa, che esiste anche in str1 , lasciando test come l'unica variabile che contiene ancora l'indirizzo del & # 8220; due & # 8221; stringa.

A proposito, stringWithCString: è obsoleto. Utilizzare invece stringWithUTF8String: o stringWithCString: encoding: .

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top