iOS判斷物件等同性

2021-07-04 17:05:51 字數 3270 閱讀 2517

物件等同性

無論我們使用什麼語言,總是會出現需要判斷兩個物件是否相等的情況,oc當然也不例外。首先看一段**:

nsstring *str1 = [[nsstring alloc] initwithcstring:"

equal

"encoding:nsutf8stringencoding];

nsstring *str2 = @"

equal";

if(str1 ==

str2)

很明顯,在我們開來,str1和str2是「相等的」。但是事實上equal是不會被列印的。這是因為如果我們直接比較兩個物件是否相等,實際上比較的是兩個物件的指標是否相等。

上述**中str1和str2是分別指向兩塊不同的記憶體的,所以肯定不會像等了。

我們稍微修改一下**再看看:

nsstring *str1 = [[nsstring alloc] initwithcstring:"

equal

"encoding:nsutf8stringencoding];

nsstring *str2 = @"

equal";

if([str1 isequal:str2])

注意看加粗語句,我們改用nsobject提供的isequal方法比較,發現"equal"被列印了出來。因為isequal在nsstring 內部被實現的時候比較的是真正的字串是否相等!

物件等同性實現

看過上面例子後,現在我們自己建立乙個類來進一步說明等同性

#import

@inte***ce

equalobject : nsobject

@property(nonatomic ,strong)nsstring *name;

@end

#import

"equalobject.h

"@implementation

equalobject

@end

定義了乙個equalobject類,有乙個name屬性。

現在我們建立兩個物件來比較一下:

equalobject *object1 = [equalobject new

]; equalobject *object2 = [equalobject new

]; if

([object1 isequal:object2])

發現**執行結束並沒有輸出"equal",原因就在於isequal方法是需要我們自己實現的。nsobject的isequal:方法預設是比較兩個物件指向的位址是否相等,這裡開闢了兩個物件肯定不想等了。

現在我們新增isequal:方法的實現:

-(bool)isequal:(id)object

return

yes;

}else

}

這裡稍微解釋一下,為什麼兩個物件不同類就呼叫父類的isequal:這是因為,有的時候我們是可以讓子類等於父類的,我們只需要關注屬性是否相同時可以這樣寫,如果不需要也可以不在父類處理那麼久預設不相等了。

現在我們不對name進行賦值操作依然是沒有值列印出來的。

修改客戶端**:

equalobject *object1 = [equalobject new

]; equalobject *object2 = [equalobject new

]; object1.name = @"

xiaoming";

object2.name = @"

xiaoming";

if([object1 isequal:object2])

發現這時候在執行就已經相等了。

為類定製等同性方法

我們可以看到nsstring除了可以用isequal比較是否相等意外,還可以使用isequaltostring來比較!這是專為nsstring類定製的等同性方法,提供這樣的方法就可以很明確我們實現了該物件的isequal方法。

下面為equalobject提供定製的等同性方法,並修改isequal:方法

- (bool)isequaltoequalobject:(equalobject *)object

- (bool)isequal:(id)object

else

}

然後客戶端修改

if

([object1 isequaltoequalobject:object2])

很順利的"equal"了...

物件hash碼

每乙個oc物件內部都是有乙個hash碼的,當物件存入集合中(array,set,hashtable等),那麼他們的hash碼會被當做鍵來決定他們該放入哪乙個集合中。

首先我們先看一下集合內部是如何儲存的

hashcode

subcollection

code1

value1,value2,value3,value4

code2

value5,value6

code3

value7

code4

value8,value9,value10

集合的內部並不像我們所想的那樣,是乙個hash表,它將插入的物件根據hashcode來決定放入哪乙個子集合。如果要刪除或者比較集合內元素,它首先根據hashcode找到子集合,然後跟子集合的每個元素比較。

所以如果我們的物件的hashcode如果都相同,那麼就會出現嚴重的效率問題,

理論上來說,我們確定等同性的兩個物件的hash應該是相同的而不等的兩個物件hash也應該不等,這樣在存入hashtable之類的集合時,就會避免相同物件的重複新增,比如我們兩個物件hash相等,但實際物件不等,那麼新增的時候就會被新增到同一subcollection下面。

所以為了避免這種情況,我們盡量自己實現一種避免重複的方式,

這裡提供一種,新增乙個新屬性age,hash實現如下:

-(nsuinteger)hash

集合中的物件等同性

我們對nsarray呼叫isequal方法,它會對集合裡的每個物件和另乙個集合相同位置的物件進行isequal:操作,只有全部相等,兩個集合才相等。

這裡說一下,集合裡面最後新增都是不可變元素,如果是可變性元素會出現不法控制的情況。

比如我們往nsset裡面新增兩個nsmutablearray,一開始兩個array不等,那麼set中就有兩個元素。

然後修改乙個array使兩個相等,這是set中就會有兩個相等的元素存在!

Objective C 判斷物件等同性

無論我們使用什麼語言,總是會出現需要判斷兩個物件是否相等的情況,oc當然也不例外。首先看一段 nsstring str1 nsstring alloc initwithcstring equal encoding nsutf8stringencoding nsstring str2 equal if...

ios開發之判斷物件的等同性isEqual

在開發中我們經常會遇到這樣的情況 判斷兩個元素或者物件是否相等。經常用到的有 或者isequal或者isequaltostring等等。下邊我們就來介紹一下這幾種方法的區別。一 操作符判斷的是兩個指標本身 也就是兩個物件的記憶體位址 而不是所指的物件。nsstring str1 bound 123 ...

iOS理解「物件等同性」這一概念

前言 最近看了一道題 nsstring s1 hello world nsstring s2 hello world 請問 s1 s2的返回值是yes還是no?相信很多童鞋的答案都是no,可能大家認為s1 s2兩個物件的位址不同,但是事實真的如此麼?為此特意寫了乙個demo來印證下 import i...