• 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保存的是数组的首地址,所以都一样。

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

  • 相关阅读:
    编程及应用中的一些快捷键(持续更新中)
    html5入门(head部分的基本认识)
    html5入门(j简单了解html)
    动态规划 ship
    js 解决两值交换
    styled-components解决全局样式'injectGlobal' 废除的问题
    mysql sql更新密码失败
    window nginx 基础命令
    MySQL 8.0
    "unexpected console statement” in Node.js
  • 原文地址:https://www.cnblogs.com/lmfboke/p/6420238.html
Copyright © 2020-2023  润新知