[ glorius @ 12.06.2013. 17:00 ] @
Preciznije, pitanje se odnosi na updateovanje liste observera u subject-u posle brisanja nekog od observera. Naravno, brisanje se ne odvija u subject objektu vec u nekoj drugoj funkciji zaduzenoj za brisanje objekata. Posle brisanja observer objekta (pomocu neke deleteObject funkcije koja se nalazi u ObjectManager objektu koji odrzava listu objekata), Subject jos uvek sadrzi pointer (koji vise nije validan) na obrisani observer objekat. Malo sam istrazivao i uvideo da postoje 3 resenja za ovo ali nisam siguran koje je najbolje. 1. U destruktoru objekta koji se brise da se pozove funkcija koja obavestava Subject(e) tog objekta da je on pred brisanjem (subject->observerAboutToRemove(this)) i da se taj objekat izbaci iz liste svih subjecta koji ga sadrze kao observer. 2. Da se obrisani observeri izbrisu iz liste u Notify funkciji: Code: // .h list<boost::weak_ptr<DObject> > m_observers; // .cpp void DObject::notify(int eventId, void *pData) { // brisemo sve expired weak_ptrs m_observers.remove_if(bind(&boost::weak_ptr<DObject>::expired, _1)); foreach(boost::weak_ptr<DObject> wpObj, m_observers) { if(boost::shared_ptr<DObject> obj = wpObj.lock()) { obj->onNotify(shared_from_this(), eventId, pData); } } } 3. Koriscenje 'Delayed deallocation' http://www.boost.org/doc/libs/...s/smart_ptr/sp_techniques.html ali cu onda morati da m_observers cuvam kao listu shared_ptr. Kreirao bih globalnu listu _objectsForRemoving i onda bih brisao sve objekte izjednom u nekom pogodnom trenutku za to, npr. u main loop. Meni se najvise dopada resenje 1. ali nisam siguran da li je dobro... Mozda se desi da u nekoj tacki i subject i observer budu nevalidni ili mozda jos neki bug... Resenje 2. je ok ali mi nije elegantno. Resenje 3. je mozda idealno, samo da se vidi u kom trenutku je najpogodnije prazniti listu obrisanih observera. Da li imate neka iskustva sa ovim interesantnim problemom i mozda neki savet kako je najbolje napraviti ovaj sistem? |