zoukankan      html  css  js  c++  java
  • 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保存的是数组的首地址,所以都一样。

      有关内存地址的知识,说实话我也不是很清楚,但是我会在后面的文章中,慢慢的进行整理,希望能将这一块彻底解决。

  • 相关阅读:
    Balanced Binary Tree
    Swap Nodes in Pairs
    Reverse Nodes in k-Group
    Reverse Linked List II
    Remove Nth Node From End of List
    Remove Duplicates from Sorted List II
    Remove Duplicates from Sorted List
    Partition List
    Merge Two Sorted Lists
    【Yii2.0】1.2 Apache检查配置文件语法
  • 原文地址:https://www.cnblogs.com/lmfboke/p/6420238.html
Copyright © 2011-2022 走看看