/ / Техники за изпълнение - хеш на променливи какаови обекти - цел-c, какао, cocoa-touch, хеш

Техники за внедряване на хапче върху обекти за какао, които могат да се променят - цел-c, какао, какао-докосване, хеш

Документацията за -hash казва, че не трябва да се променя, докато обект с променлива памет се съхранява в колекция и по подобен начин документацията за -isEqual: казва -hash стойността трябва да бъде еднаква за равни обекти.

Имайки предвид това, някой има ли някакви предложения за най-добрия начин за изпълнение -hash така, че отговаря на двете условия и все пак се изчислява интелигентно (т.е. просто не се връща) 0)? Някой знае ли как променливите версии на предоставените от рамката класове правят това?

Най-простото нещо е да забравитепървото условие (за това да не се променя) и просто се уверете, че никога не случайно мутирам обект, докато той е в колекция, но аз съм се чудех дали има някакво решение, което е по-гъвкаво.

РЕДАКТИРАНЕ: Чудя се дали е възможноподдържайте 2 договора (където равните обекти имат еднакви хешове и хешовете не се променят, докато обектът е в колекция), когато аз "m" мутирам вътрешното състояние на обекта. Моята склонност е да кажа "не", освен ако не направя нещо глупаво, както винаги се връща 0 за хеша, но затова и задавам този въпрос.

Отговори:

2 за отговор № 1

Интересен въпрос, но мисля, че това, което искатее логически невъзможно. Кажете, че започнете с 2 обекта, А и Б. И двете са различни и започват с различни хеш-кодове. Добавяте и двете към някаква хеш-таблица. защото е вече в таблицата. Въпреки това е възможно да се промени А по такъв начин, че той да е равно на () Б.

В този случай имате 2 възможности за избор, нито един от които не работи:

  1. Променете хеш-кода на A на равен на B.hashcode, който нарушава ограничението за непроменяне на хеш-кодовете в хеш-таблицата.
  2. Не променяйте хеш-кода, в който случай A.equals (B), но те нямат едни и същи хаш-кодове.

Струва ми се, че не е възможно да се направи това, без да се използва константа като хеш-код.


2 за отговор № 2

Моето четене на документацията е, че стойността на променливия обект е за hash мога (и вероятно трябва) да се променят, когато се мутират, но не трябва промяна, когато обектът не е бил мутиран. Следователно частта от документацията, към която се отнася, казва: "Не мутирайте обекти, които се съхраняват в колекция, защото това ще предизвика hash стойност за промяна. "

За да цитирате директно от Документация за обекта hash:

Ако в a се добави променлив обект това събиранеизползва хеш стойности за определяне на позицията на обекта в събиране, стойността, върната от хеш методът на обекта не трябва промените, докато обектът е в колекция. Следователно или хеш методът не трябва да разчитана всеки от информация за вътрешното състояние на обекта или трябва да се уверите, че обектът е вътрешната информация за състоянието не промените, докато обектът е в колекция.

(Акцентът ми.)


1 за отговор № 3

Въпросът тук не е как да отговорим на двете изисквания, а кой Трябва Среща. В документацията на Apple ясно се посочва, че:

сменяем речник може да бъде поставен в хеш таблица, но не трябва да го променяте, докато е там.

Казано по-скоро, изглежда по-важно виеотговарят на изискването за равенство на хешовете. Хешът на обекта трябва винаги да бъде начин да се провери дали даден обект е равен на друг. Ако това никога не е така, това не е истинска хеш функция.

Само за да довърша отговора си, ще дам пример за добро изпълнение на хаш. Да речем, че пишете изпълнението на -hash върху колекция, която сте създали. Тази колекция съхранява масив от NSObjects като указатели. Тъй като всички NSObjects изпълняват хеш функцията, можете да използвате техните хешове при изчисляване на хеша на колекцията:

- (NSUInteger)hash {
NSUInteger theHash = 0;
for (NSObject * aPtr in self) { // fast enumeration
theHash ^= [aPtr hash];
}
return theHash;
}

По този начин два обекта за събиране, съдържащи едни и същи указатели (в същия ред), ще имат същия хеш.


0 за отговор № 4

Тъй като вече преобръщате -isEqual: за да направите сравняване на стойност, сигурни ли сте, че наистина трябва да се занимавате с -hash?

Не мога да позная какво точно имате нужда от товаразбира се, но ако искате да направите сравнение на базата на стойността, без да се отклонявате от очакваното изпълнение на -isEqual: да върнете само YES, когато хешовете са идентични, по-добър подход може да бъде да се имитира NSString 's -isEqualToString :, така че да създадете свои собствени -isEqualToFoo: метод вместо използване или презаписване -isEqual :.


-2 за отговор № 5

В Java повечето променливи класове просто не могат да бъдат заменени Object.hashCode () така, че изпълнението по подразбиране връща стойност, която се основава на адреса на обекта и не се променя. Може да е същото и с Цел C.