国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

Objective-C——判斷對象等同性

2019-11-14 18:32:44
字體:
來源:轉載
供稿:網友

對象等同性

無論我們使用什么語言,總是會出現需要判斷兩個對象是否相等的情況,OC當然也不例外。首先看一段代碼:

        NSString *str1 = [[NSString alloc] initWithCString:"equal" encoding:NSUTF8StringEncoding];        NSString *str2 = @"equal";        if(str1 == str2)        {            NSLog(@"equal");        }

很明顯,在我們開來,str1和str2是“相等的”。但是事實上equal是不會被打印的。這是因為如果我們直接比較兩個對象是否相等,實際上比較的是兩個對象的指針是否相等。

上述代碼中str1和str2是分別指向兩塊不同的內存的,所以肯定不會像等了。

我們稍微修改一下代碼再看看:

        NSString *str1 = [[NSString alloc] initWithCString:"equal" encoding:NSUTF8StringEncoding];        NSString *str2 = @"equal";        if([str1 isEqual:str2])        {            NSLog(@"equal");        }

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

 

對象等同性實現

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

#import <Foundation/Foundation.h>@interface 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]) {        NSLog(@"equal"); }

發現代碼運行結束并沒有輸出"equal",原因就在于isEqual方法是需要我們自己實現的。NSObject的isEqual:方法默認是比較兩個對象指向的地址是否相等,這里開辟了兩個對象肯定不想等了。

現在我們添加isEqual:方法的實現:

-(BOOL)isEqual:(id)object{    if([self class] == [object class])    {        if(![self.name isEqual:[(EqualObject *)object name]])        {            return NO;        }        return YES;    }    else    {        return [super isEqual:object];    }}

這里稍微解釋一下,為什么兩個對象不同類就調用父類的isEqual:這是因為,有的時候我們是可以讓子類等于父類的,我們只需要關注屬性是否相同時可以這樣寫,如果不需要也可以不在父類處理那么久默認不相等了。

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

修改客戶端代碼:

        EqualObject *object1 = [EqualObject new];        EqualObject *object2 = [EqualObject new];        object1.name = @"xiaoming";        object2.name = @"xiaoming";                if([object1 isEqual:object2])        {            NSLog(@"equal");        }

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

 

為類定制等同性方法

我們可以看到NSString除了可以用isEqual比較是否相等意外,還可以使用isEqualToString來比較!這是專為NSString類定制的等同性方法,提供這樣的方法就可以很明確我們實現了該對象的isEqual方法。

下面為EqualObject提供定制的等同性方法,并修改isEqual:方法

- (BOOL)isEqualToEqualObject:(EqualObject *)object{    if(self == object)        return YES;    if(![self.name isEqualToString:object.name])        return NO;    return YES;}- (BOOL)isEqual:(id)object{    if([self class] == [object class])    {        return [self isEqualToEqualObject:object];    }    else    {        return [super isEqual:object];    }}

然后客戶端修改

        if([object1 isEqualToEqualObject:object2])        {            NSLog(@"equal");        }

很順利的"equal"了...

 

對象hash碼

每一個OC對象內部都是有一個hash碼的,當對象存入集合中(Array,Set,HashTable等),那么他們的hash碼會被當做鍵來決定他們該放入哪一個集合中。

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

hashCodesubCollection
code1value1,value2,value3,value4
code2value5,value6
code3value7
code4value8,value9,value10

 

 

 

 

 

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

所以如果我們的對象的hashCode如果都相同,那么就會出現嚴重的效率問題,

理論上來說,我們確定等同性的兩個對象的hash應該是相同的而不等的兩個對象hash也應該不等,這樣在存入hashTable之類的集合時,就會避免相同對象的重復添加,比如我們兩個對象hash相等,但實際對象不等,那么添加的時候就會被添加到同一subCollection下面。

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

這里提供一種,添加一個新屬性age,hash實現如下:

- (NSUInteger)hash{    NSUInteger nameHash = [_name hash];    NSUInteger ageHash = _age;    return nameHash ^ ageHash;}

 

集合中的對象等同性

我們對NSArray調用isEqual方法,它會對集合里的每個對象和另一個集合相同位置的對象進行isEqual:操作,只有全部相等,兩個集合才相等。

這里說一下,集合里面最后添加都是不可變元素,如果是可變性元素會出現不法控制的情況。

比如我們往NSSet里面添加兩個NSMutableArray,一開始兩個array不等,那么set中就有兩個元素。

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


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 邛崃市| 延吉市| 星子县| 江陵县| 宣城市| 衢州市| 宁都县| 聂荣县| 鹤山市| 泸州市| 丹寨县| 天峻县| 湛江市| 鱼台县| 赤壁市| 双峰县| 荔波县| 宁津县| 磴口县| 黄浦区| 股票| 汉源县| 肇源县| 福泉市| 尼木县| 财经| 大同市| 郁南县| 边坝县| 丹棱县| 达日县| 临漳县| 房山区| 蛟河市| 方山县| 景谷| 崇仁县| 苍梧县| 勐海县| 祁连县| 台州市|