iOS 数组containsObject:方法
今年上半年打算巩固一下基础知识,将工作和学习中遇到的疑惑尽量搞清楚原理。作为一个菜鸟级别的程序员,我深深的体会到算法和基础的重要性,如果说算法是内功,那么基础就是下盘,只有下盘稳住了,上面才不会轻易倒。当然,我这里刻意避开算法不谈,实际上我知道自己不是研究算法的料,想来懂一些基本的算法就好了,以后若是遇到莫大的机缘,习得一两本内功心法,那时我可能要上天了。哈哈,不晓得能不能听懂我的胡言乱语。
之前遇到过一个问题,从数据库中读数据后发现有重复的数据出现,而且读数据库是采取一次性读完的方式,从理论上讲是不会出现重复数据的现象的。查了一下代码,发现并没有什么问题,因为时间的原因,而且是帮别人解决问题,所以也就没有深究。最后写了个去重复的方法,用来保证不会显示同样的数据。去重复的方法很简单,但是重点不是它,我想说的是如果想偷懒的童鞋想用数组中的containsObject:方法去重复就要注意了,因为这个方法没有我们想象的那么强大。我用两种方式来检测这个方法到底在做什么事。
1.使用字符串测试。首先创建几个字符串,@"123", @"456", @"123", @"222",把它们添加到数组中去。为了节省时间,直接放入不可变数组中,NSArray *strArray = @[@"123", @"456", @"123", @"222"];然后创建一个可变数组,NSMutableArray *testStrArray = [NSMutableArray array];依次将strArray中的对象添加到testStrArray中,在此之前用containsObject:判定testStrArray中是否已经存在了,如果没有存在,则添加。看如下代码:
//1.字符串常量的比较,测试对象:@"123", @"456", @"123", @"222"
NSString *str1 = @"";
NSString *str2 = @"";
NSString *str3 = @"";
NSArray *strArray = @[str1, str2, str3];
NSMutableArray *testStrArray = [NSMutableArray array];
for (NSString *str in strArray)
{
if ([testStrArray containsObject:str])
{
NSLog(@"%@ 已存在 地址是 %p", str, &str);
}
else
{
NSLog(@"%@ %p", str, &str);
[testStrArray addObject:str];
}
}
NSLog(@"%@ %p", testStrArray, &testStrArray);
NSLog(@"%p", str1);
NSLog(@"%p", str2);
NSLog(@"%p", str3);
下面看看输出结果:

看看最下面三行,你会发现第一个和第三的地址相同,然后在数组中添加了两个对象,说明这个方法能够将字符串去重复。那么到底是根据什么去重复的我们不得而知,因为这里有两个因素:1.字符串内容相同,都是@"123";2.地址相同。下面用自定义的对象测试完了之后,再来说说为什么str1和str3的地址相同,以及在for循环中打印出来的str的地址为什么相同。
2.使用自定义的对象测试,套路跟字符串一样,代码如下:
TestObject *testObj1 = [[TestObject alloc] initWithName:@""];
TestObject *testObj2 = [[TestObject alloc] initWithName:@""];
TestObject *testObj3 = [[TestObject alloc] initWithName:@""];
TestObject *testObj4 = [[TestObject alloc] initWithName:@""];
NSArray *testArray = @[testObj1, testObj2, testObj3, testObj4, testObj1];
NSMutableArray *testMutableArray = [NSMutableArray array];
for (int i=;i<[testArray count];i++)
{
TestObject *testObj = testArray[i];
if ([testMutableArray containsObject:testObj])
{
NSLog(@"%@-------------%p", testObj, &testObj);
}
else
{
// NSLog(@"%@ %p %li", testObj, &testObj, sizeof(testObj));
[testMutableArray addObject:testObj];
}
}
NSLog(@"%@", testMutableArray);
NSLog(@"1 %p", testObj1);
NSLog(@"2 %p", testObj2);
NSLog(@"3 %p", testObj3);
NSLog(@"4 %p", testObj4);
输出的结果如下:

第一个对象添加了两次,去重复将其去掉了,然而内容相同的testObj1和testObj3并没有去重复,由此可以看出,这个方法并不能将内容相同的对象区别开来。
其实,做这个实验是想说明,containsObject:是在比较内存地址,即使两个对象内容完全一样,地址不同,那也是不同的。我个人认为这个方法应该叫是否存在同一个对象,因为根据字面意思,我们有时候可能会因为想偷懒,而人为的把它假想成内容一样就是对象一样。
接下来说说字符串这个东西,不可变字符串是一种很特殊的对象,它初始化的时候,通常指向字符串常量,所以str = @"123"表示的是,str存放了@"123"地址,固第一种测试中的str1和str3地址相同。在for循环中打印str的地址时,发现都相同,是因为,str保存的是数组的首地址,所以都一样。
有关内存地址的知识,说实话我也不是很清楚,但是我会在后面的文章中,慢慢的进行整理,希望能将这一块彻底解决。
iOS 数组containsObject:方法的更多相关文章
- IOS开发_中遍历数组的方法及比较
数组,做为一种常用的数据类型,频繁出现在编码中,其中肯定少不了对数组的遍历,本博文对数组遍历,进行一下自己的归纳,如果是大牛,一笑而过就好,互相学习,欢迎指正. 话不多说直接进入主题 首先创建一个数组 ...
- iOS常用公共方法
iOS常用公共方法 字数2917 阅读3070 评论45 喜欢236 1. 获取磁盘总空间大小 //磁盘总空间 + (CGFloat)diskOfAllSizeMBytes{ CGFloat si ...
- iOS数组使用
相关链接: ios数组基本用法和排序 NSArray 排序汇总 iOS 数组排序方法 IOS-筛选数组内的元素 关于EnumerateObjectsUsingBlock和for-in之间的较量 [iO ...
- [BS-02] iOS数组、字典、NSNumber 新写法—— @[]、@{}
IOS数组.字典.NSNumber 新写法—— @[].@{} //标准写法 NSNumber * number = [NSNumber numberWithInt:]; NSArray * ar ...
- iOS 常用公共方法
iOS常用公共方法 1. 获取磁盘总空间大小 //磁盘总空间 + (CGFloat)diskOfAllSizeMBytes{ CGFloat size = 0.0; NSError *error; N ...
- ES6之数组扩展方法【一】(相当好用)
form 转化为真正的数组 先说一下使用场景,在Js中,我们要经常操作DOM,比如获取全部页面的input标签,并且找到类型为button的元素,然后给这个按钮注册一个点击事件,我们可能会这样操作: ...
- 再探JS数组原生方法—没想到你是这样的数组
最近作死又去做了一遍javascript-puzzlers上的44道变态题,这些题号称"JS语言专业八级"的水准,建议可以去试试,这里我不去解析这44道题了, ...
- 一些ES5的操作数组的方法
在ES5规范中新增了不少操作数组的方法,特此罗列一下以备使用 1. forEach循环 有点类似jQuery的each循环 [12,23,36,4,5].forEach(function(v,k){ ...
- 关于ES3、ES5、ES6以及ES7所有数组的方法(api)的总结
起因:工作用经常用到操作数组的方法,这里进行一下总结,我尽量以简洁的语言概括每个方法(api)的作用.如果您想快速定位,可以Control+F 然后搜相应的方法即可定位 :) ES3的数组方法 joi ...
随机推荐
- OpenJudge百炼习题解答(C++)--题4074:积水量
题: 总时间限制: 1000ms 内存限制:65536kB 描写叙述 凹凸不平的地面每当下雨的时候总会积水.如果地面是一维的.每一块宽度都为1,高度是非负整数.那么能够用一个数组来表达一块 ...
- Django--ORM基础
ORM(映射关系) 映射关系: 表名 <-------> 类名 字段 <-------> 属性 表记录 <------->类实例对象 创建表(建立模型) 在Djan ...
- HDOJ 4884 & BestCoder#2 1002
TIANKENG’s rice shop Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Oth ...
- mahout相关介绍
https://blog.csdn.net/xiaopihaierletian/article/details/72674592 https://www.cnblogs.com/zlslch/p/67 ...
- Jquery学习笔记(11)--jquery的ajax删除用户,非常简单!
jquery的ajax,简直简单!!只要一个$.get(url,map,function)就搞定了! index.php: <!DOCTYPE html> <html lang=&q ...
- linux学习笔记23--时间命令date和cal
在linux环境中,不管是编程还是其他维护,时间是必不可少的,也经常会用到时间的运算,熟练运用date命令来表示自己想要表示的时间,肯定可以给自己的工作带来诸多方便. 1.命令格式: date [参数 ...
- ExtFormReturn,ext
package cn.edu.hbcf.common.vo; public class ExtFormReturn { /** * 是否成功 */ private boolean success; / ...
- httpClient使用中报错org.apache.commons.httpclient.HttpMethodBase - Going to buffer response body of large or unknown size.
在使用HttpClient发送请求,使用httpMethod.getResponseBodyAsString();时当返回值过大时会报错: org.apache.commons.httpclient. ...
- 理解Java中字符流与字节流
1. 什么是流 Java中的流是对字节序列的抽象,我们可以想象有一个水管,只不过现在流动在水管中的不再是水,而是字节序列.和水流一样,Java中的流也具有一个"流动的方向",通常可 ...
- Service Mesh服务网格新生代--Istio(转)
万字解读:Service Mesh服务网格新生代--Istio 官网地址:https://preliminary.istio.io/zh/docs/concepts/security/ Servic ...