Por que as variáveis ??se comportam de modo estranho?
-
03-07-2019 - |
Pergunta
Eu pensei que uma variável em Objective-C é apenas uma referência a um lugar objeto na memória. Assim, para o meu entendimento, o resultado deve ter sido "um", porque no final i atribuir endereço de memória do objeto de str1 que str2, e, anteriormente, eu tive assignend o endereço de memória de str2 para teste.
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" ??
Solução
Esta é a forma como ponteiros trabalhar. O resultado você vê é normal e correto.
Vamos lista de todas as suas variáveis ??e que amarra eles apontam para na memória como eles são declarados:
str1 -> "One"
str2 -> "Two"
Em seguida, você executar algumas instruções da atribuição:
test = str2;
Este atribui o valor da str2
ponteiro para test
. Assim, os ponteiros são
str1 -> "One"
str2 -> "Two"
test -> "Two"
Em seguida
str2 = str1;
Atribui o valor da str1
ponteiro para str2
. Agora, os ponteiros são
str1 -> "One"
str2 -> "One"
test -> "Two"
Em seguida, você imprimir test
, que está apontando para o que str2
estava apontando para originalmente, que é "Two".
Eu acho que você pensa que desde que você atribuiu str2
ao valor do str1
e test
ao valor do str2
, que o valor de str1
alguma forma cascatas em test
. Este não é o caso. Uma vez que o valor da test
é atribuído, a informação sobre onde esse valor vieram de está perdido. Se quiser valor de test
ser o mesmo que str1
de, você tem você inverter a ordem das suas operações de cessão de:
str2 = str1;
test = str2;
Outras dicas
Você tem isso:
test = str2; // test is an instance variable.testing!
str2 = str1;
NSLog(test); // = "two" ??
Agora, vamos fingir que todas essas variáveis ??foram ints.
Na primeira linha, test
variável é definida como o valor de str2
variável.
Na segunda linha, str2
variável é definido como o valor de str1
variável.
Na terceira linha, nós imprimir o valor de test
, e é de fato o valor que str2
foi quando atribuído str2
para teste.
Realmente não importa em str2
tudo o que posteriormente atribuído um valor diferente.
Ok, mas as variáveis ??são realmente ponteiros, você diz, não ints.
Não importa: pensar em um ponteiro como apenas um número, o endereço de algum lugar na memória. E de passagem, que a NSLog faz NSLog imprimir não o valor do ponteiro, mas o valor do que o ponteiro aponta para, que é uma matriz de char.
Uma variável é um recipiente. A atribuição leva tudo o que está no lado direito e coloca-lo também em tudo o que está no lado esquerdo. Em outras palavras, ele copia o valor de uma variável para o outro; neste caso, esses valores são ponteiros (endereços de memória).
Então aqui está o que você fez:
- Leve o endereço que está na variável
str2
e colocar o mesmo endereço na variáveltest
. - Leve o endereço que está na variável
str1
e colocar o mesmo endereço na variávelstr2
.
Passo 2 não afeta a variável test
; sua única atribuição para essa variável foi na etapa 1.
Importante: Você não está copiando o que está em o endereço; você está copiando o próprio endereço . Ainda há apenas um “dois” string, mas entre os passos 1 e 2, o endereço do objeto é tanto str2
e test
. Em seguida, na etapa 2, você substituir o endereço em str2
com o endereço do “um” string, que também existe em str1
, deixando test
como a única variável que ainda detém o endereço do “dois” string.
BTW, stringWithCString:
está obsoleta. Use stringWithUTF8String:
ou stringWithCString:encoding:
vez.