NSMutable属性声明时为什么不能使用copy
在iOS开发里面我们经常会进行NSMutable(可变类型的类,常用的如NSMutableString,NSMutableArray,NSMutableDictionary,NSMutableData等)属性的声明,在声明时我们都知道要使用strong(强引用)来进行标识,但是很多人不知道为什么不能使用copy来进行标识,下面我们展开讨论一下:
1.为什么不能使用copy:
总所周知,所有的可变类都是继承于非可变类的,属于可变类的子类,拿NSMutableString类来举例,大家进入到NSMutableString类的.h文件可以看到它是继承于NSString类的,而且NSMutableString类并没有重写NSString类的copy方法,所以我们如果声明NSMutableString类属性时使用了copy进行标识,在我们对这个属性进行赋值时,调用的其实是NSString类的copy方法,拿到的实例对象其实是一个NSString的实例,而不是一个NSMutableString的实例,下面使用代码给大家验证一下:

从输出结果可以看到tempStr是一个NSMutableString对象,使用strong修饰声明的属性str只是对tempStr对象添加了一个引用计数,并没有产生新的对象实例,所以tempStr和str的class方法其实调用的是同一个对象的方法,所以输出的结果是一样的。而使用copy修饰声明的属性mstr在被赋值时,会调用tempStr对象的copy方法产生一个新的对象,而且从输出结果可以看到这个对象是NSString对象。
综上所述,NSMutable属性声明时不能使用copy进行修饰是因为NSMutable类并没有重写非可变类的copy方法,给属性赋值时,调用的是父类的copy方法,得到的对象是一个非可变对象。
2.使用了copy会怎样:
由于给对象赋值时得到的对象是非可变对象,所以我们使用该属性调用可变对象的特有方法时程序会奔溃(因为对象根本响应不了该方法),下面我们同样适用代码给大家验证一下:

tempStr对象和str属性的replaceCharactersInRange方法均执行成功,但是程序运行到[self.mstr replaceCharactersInRange:NSMakeRange(0, 1) withString:@""]这句代码时奔溃了,所以这个问题对程序的影响还是很大的,而且这个的bug很难被找出来,所以在声明NSMutable属性时一定要多加注意。
第一次写博客,希望对大家有所帮助,博文中有什么不足的地方希望各位大牛可以帮忙指出,大家一起交流进步
NSMutable属性声明时为什么不能使用copy的更多相关文章
- nsmutablestring 属性声明为copy程序崩溃了
obj.mutableStr = (NSMutableString *)[[NSMutableString alloc] initWithString:@"Hello"]; NSL ...
- iOS: 属性声明strong和retain竟然不一样
今天和同事在处理一处用strong声明的Block属性引发的问题时偶然发现的.在诸多教程中都会讲到:声明属性时用strong或者retain效果是一样的(貌似更多开发者更倾向于用strong).不过在 ...
- iOS的属性声明:retain和strong的区别
声明属性时用strong或者retain效果是一样的(貌似更多开发者更倾向于用strong).不过在声明Block时,使用strong和retain会有截然不同的效果.strong会等于copy,而r ...
- HTML编码规则、CSS属性声明顺序--简介
From AmazeUI:http://amazeui.org/getting-started/html-css-guide HTML 属性顺序 HTML 属性应当按照以下给出的顺序依次排列,确保代码 ...
- 在Javascript中 声明时用"var"与不用"var"的区别,== 和 ===的区别
今天,被问到两个JS问题,当时没回答到重点,问题虽然看起来简单,但是细节却马虎不得,在此做下记录: 1. 在Javascript中 声明时用"var"与不用"var&qu ...
- Visual Studio《加载此属性页时出错》的解决办法
打开aspx页面时不能切换到设计视图,vs 2008工具箱中无控件.打开vs 2008的工具>选项>HTML设计器时提示:加载此属性页时出错 有时还会有其它错误提示,比如打开一个Windo ...
- 属性声明(property declarations), 自定义属性,自动生成 get 和 set 方法,getter 和 setter
属性声明(property declarations), 自定义属性,自动生成 get 和 set 方法,getter 和 setter 一.普通的get 和set 属性. 一般的get 和set 属 ...
- iOS:不同属性声明方式的解析
代码: /* 属性声明方式说明: ----------------------- 1 @interface ... { id name } @end 这样声明的属性其实可以认为是private属性,因 ...
- <jsp:param>标签给属性赋值时的一个坑
http://blog.sina.cn/dpool/blog/s/blog_58c5066001011gdn.html 因为: <jsp:forward和<jsp:param在被编译成ja ...
随机推荐
- apt-get命令失效
1.linux体系区分 a.ded体系,例如debian系统.ubuntu系统.使用apt-get命令: 例如:sudo apt-get install apache2 b.rpm体系,例如redha ...
- My first_leetcode_Rever Ingeter 数字翻转java实现(办法集合)
7. Reverse Integer Reverse digits of an integer. Example1: x = 123, return 321 Example2: x = -123, ...
- mysql存储过程详细讲解及完整实例下载
一.存储过程概念 1.存储过程(Stored Procedure)是一组为了完成特定功能的SQL语句集.经编译后存储在数据库 中. 2.存储过程是数据库中的一个重要对象,用户通过指定存储过程的名字并给 ...
- Heritrix工具实现网络爬虫
上次用的java相关知识实现了一个简单的网络爬虫,现在存在许多开源免费的爬虫工具,相对来说,可以很简单的获取网页数据,并写入到本地. 下面我就阐述一下我用Heritrix爬虫工具实现网页数据爬取. - ...
- 甲方VS乙方
甲方与乙方,在很多人都存在有误解,不知道究竟如何辨别.这里我提一些简单的辨别方式:甲方一般是指提出目标的一方,在合同拟订过程中主要是提出要实现什么目标,乙方一般是指完成目标,在合同中主要是提出如何保证 ...
- Qt实现九宫图类控件
<1>. 头文件(类声明) class CPreviewWidge : public QWidget { Q_OBJECT public: CPreviewWidge( ); ~CPrev ...
- 你不可不看的Android开发命名规范
标识符命名法最要有四种: Camel(骆驼)命名法:除首单词外,其余所有单词的第一个字母大写,如:fooBar; Pascal命名法:所有单词的第一个字母大写,如:FooBar: 下划线命名法:单词与 ...
- 1、初识socket
经过近一个半月的学习我们已经度过了python基础的阶段,今天我们开始学习python网络编程,没有难以理解的逻辑,更注重的是记忆. 对网络协议和基础没有概念的可以在阅读本文前预习计算机基础3.网络协 ...
- css基础知识之属性选择器
css属性选择器及属性和值选择器如下: <!DOCTYPE html> <html lang="en"> <head> <meta cha ...
- 在Python3.5中使用 The del.icio.us API
问题:参考<集体智慧编程>一书的第二章中访问del.icio.us网站的数据需要使用到事先编好的Python API.但是书上提供的API并不适用与Python3.5的版本. 解决方法:在 ...