iOS 數組containsObject:方法


  今年上半年打算鞏固一下基礎知識,將工作和學習中遇到的疑惑盡量搞清楚原理。作為一個菜鳥級別的程序員,我深深的體會到算法和基礎的重要性,如果說算法是內功,那么基礎就是下盤,只有下盤穩住了,上面才不會輕易倒。當然,我這里刻意避開算法不談,實際上我知道自己不是研究算法的料,想來懂一些基本的算法就好了,以后若是遇到莫大的機緣,習得一兩本內功心法,那時我可能要上天了。哈哈,不曉得能不能聽懂我的胡言亂語。

  之前遇到過一個問題,從數據庫中讀數據后發現有重復的數據出現,而且讀數據庫是采取一次性讀完的方式,從理論上講是不會出現重復數據的現象的。查了一下代碼,發現並沒有什么問題,因為時間的原因,而且是幫別人解決問題,所以也就沒有深究。最后寫了個去重復的方法,用來保證不會顯示同樣的數據。去重復的方法很簡單,但是重點不是它,我想說的是如果想偷懶的童鞋想用數組中的containsObject:方法去重復就要注意了,因為這個方法沒有我們想象的那么強大。我用兩種方式來檢測這個方法到底在做什么事。

  1.使用字符串測試。首先創建幾個字符串,@"123", @"456", @"123", @"222",把它們添加到數組中去。為了節省時間,直接放入不可變數組中,NSArray *strArray = @[@"123", @"456", @"123", @"222"];然后創建一個可變數組,NSMutableArray *testStrArray = [NSMutableArray array];依次將strArray中的對象添加到testStrArray中,在此之前用containsObject:判定testStrArray中是否已經存在了,如果沒有存在,則添加。看如下代碼:

 1 //1.字符串常量的比較,測試對象:@"123", @"456", @"123", @"222"
 2     NSString *str1 = @"123";
 3     NSString *str2 = @"345";
 4     NSString *str3 = @"123";
 5     NSArray *strArray = @[str1, str2, str3];
 6     NSMutableArray *testStrArray = [NSMutableArray array];
 7     for (NSString *str in strArray)
 8     {
 9         if ([testStrArray containsObject:str])
10         {
11             NSLog(@"%@  已存在   地址是   %p", str,  &str);
12         }
13         else
14         {
15             NSLog(@"%@     %p", str,  &str);
16             [testStrArray addObject:str];
17         }
18     }
19     NSLog(@"%@    %p", testStrArray, &testStrArray);
20     NSLog(@"%p", str1);
21     NSLog(@"%p", str2);
22     NSLog(@"%p", str3);

  下面看看輸出結果:

  看看最下面三行,你會發現第一個和第三的地址相同,然后在數組中添加了兩個對象,說明這個方法能夠將字符串去重復。那么到底是根據什么去重復的我們不得而知,因為這里有兩個因素:1.字符串內容相同,都是@"123";2.地址相同。下面用自定義的對象測試完了之后,再來說說為什么str1和str3的地址相同,以及在for循環中打印出來的str的地址為什么相同。

  2.使用自定義的對象測試,套路跟字符串一樣,代碼如下:

 1 TestObject *testObj1 = [[TestObject alloc] initWithName:@"123"];
 2     TestObject *testObj2 = [[TestObject alloc] initWithName:@"1234"];
 3     TestObject *testObj3 = [[TestObject alloc] initWithName:@"123"];
 4     TestObject *testObj4 = [[TestObject alloc] initWithName:@"1235"];
 5     NSArray *testArray = @[testObj1, testObj2, testObj3, testObj4, testObj1];
 6     NSMutableArray *testMutableArray = [NSMutableArray array];
 7     for (int i=0;i<[testArray count];i++)
 8     {
 9         TestObject *testObj = testArray[i];
10         if ([testMutableArray containsObject:testObj])
11         {
12             NSLog(@"%@-------------%p", testObj, &testObj);
13         }
14         else
15         {
16 //            NSLog(@"%@       %p      %li", testObj, &testObj, sizeof(testObj));
17             [testMutableArray addObject:testObj];
18         }
19     }
20     NSLog(@"%@", testMutableArray);
21     NSLog(@"1     %p", testObj1);
22     NSLog(@"2     %p", testObj2);
23     NSLog(@"3     %p", testObj3);
24     NSLog(@"4     %p", testObj4);

  輸出的結果如下:

  第一個對象添加了兩次,去重復將其去掉了,然而內容相同的testObj1和testObj3並沒有去重復,由此可以看出,這個方法並不能將內容相同的對象區別開來。

  其實,做這個實驗是想說明,containsObject:是在比較內存地址,即使兩個對象內容完全一樣,地址不同,那也是不同的。我個人認為這個方法應該叫是否存在同一個對象,因為根據字面意思,我們有時候可能會因為想偷懶,而人為的把它假想成內容一樣就是對象一樣。

  接下來說說字符串這個東西,不可變字符串是一種很特殊的對象,它初始化的時候,通常指向字符串常量,所以str = @"123"表示的是,str存放了@"123"地址,固第一種測試中的str1和str3地址相同。在for循環中打印str的地址時,發現都相同,是因為,str保存的是數組的首地址,所以都一樣。

  有關內存地址的知識,說實話我也不是很清楚,但是我會在后面的文章中,慢慢的進行整理,希望能將這一塊徹底解決。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM