Przejdź do treści

Adres obiektu w pamięci – Łopatologicznie

Ostatnio nieźle zacząłem gwiazdorzyć, ale już wracam do pracy. Koduję właśnie system zapisów do gry. Tak, wiem już niejeden napisałem, ale tym razem zrobię to za pomocą serializacji. Podczas pisania zauważyłem ciekawą zależność. Prawdopodobnie powinienem już o tym wcześniej wiedzieć, ale wiadomo jak to z programowaniem bywa. Oto przykład:

Health = 100;
CurrHealth = 50;
GameControl.PutObject (this);
Health = 70;
Debug.Log (((PlayerData)GameControl.GetObject (this)).Health);

Niby wszystko ok, ale ostatnia linijka zwraca mi 70. Skąd to się bierze? Oto odpowiedź.

GameControl.PutObject(this); 

Wrzuca mi dany obiekt do Dictionary przechowującego parametry obiektów wg. ich adresów. Dzięki temu cały czas będzie się odwoływała do tego obiektu na którym pracuję. W tym przypadku zmieniłem poziom zdrowia.

((PlayerData)GameControl.GetObject (this)).Health;

Tutaj natomiast ( od lewej ) rzutuję na klasę PlayerData, a następnie wywołuję metodę GetObject z klasy GameControl która zwraca mi object. Po rzutowaniu ( kolejność wykonywania działań ) pobieram parametr Health. Skomplikowane? Już wyjaśniam.

Dzwonisz do mnie pod numer 500 800 900. Mam na sobie czerwoną koszulkę. Pytasz mnie o koszulkę, ja mówię Ci że jest ona czerwona. Po rozmowie ją zmieniam i ponownie do mnie dzwonisz i pytasz o koszulkę. Mam zieloną. Ja mam ten sam numer. Pytasz się tej samej osoby, bo ja zmieniłem parametr, a nie numer.

Dalej skomplikowane? Popracuję nad tym, ale jak na razie wiedzcie, że podając this jako parametr tak na prawdę podajecie adres w pamięci, a nie jego wszystkie właściwości. Jak natomiast przekazać cały obiekt i nie modyfikować już go? Rozwiązaniem jest Clone zawarte w interfejsie ICloneable. Przykład:

public class PlayerData : MonoBehaviour, ICloneable {

public int Health = 0;
private int CurrHealth = 0;

void Start() {
Health = 100;
CurrHealth = 50;
GameControl.PutObject (this);
}

public object Clone() {
return this.MemberwiseClone ();
}
}

A jak tego użyć?

void CloneThisShit(object _player){
PlayerData player = (PlayerData) _player;
player = player.Clone();
}

Dzięki temu w pamięci mamy klona naszego obiektu. Ten na którym pracujemy jest bez zmian, a jeżeli chcemy Aktualizować jego stan wystarczy CloneThisShit(this);