16.说一说iOS中与属性成员相关的坑
2015-11-06 15:36
369 查看
之前在做项目的时候遇到的属性相关的一些坑,当时不求甚解,只要改好就ok,今天忽然看到了曾经遇到的坑的解释,就在这里做一个总结:
后来我通过加上@synthesize array = _array, 当时并不知道为什么会这样,但今天看了下面这个面试题的回答有了明悟,原文如下:
在有了自动合成属性实例变量之后,@synthesize还有哪些使用场景?
回答这个问题前,我们要搞清楚一个问题,什么情况下不会autosynthesis(自动合成)?(实例变量 = 成员变量 = ivar)
同时重写了setter和getter时
重写了只读属性的getter时
使用了@dynamic时
在 @protocol 中定义的所有属性
在 category 中定义的所有属性
重载的属性
当你在子类中重载了父类中的属性,你必须 使用@synthesize来手动合成ivar。
除了后三条,对其他几个我们可以总结出一个规律:当你想手动管理@property的所有内容时,你就会尝试通过实现@property的所有“存取方法”(the accessor methods)或者使用@dynamic来达到这个目的,这时编译器就会认为你打算手动管理@property,于是编译器就禁用了autosynthesis(自动合成)。
因为有了autosynthesis(自动合成),大部分开发者已经习惯不去手动定义ivar,而是依赖于autosynthesis(自动合成),但是一旦你需要使用ivar,而autosynthesis(自动合成)又失效了,如果不去手动定义ivar,那么你就得借助@synthesize来手动合成ivar。
以上已经说的足够明白,所以上面的错误也可以通过手动声明一个_array的成员变量得到解决。
根据iOS里一切皆对象,所以对于对象的赋值都是传一个对象的引用,如果我想在赋值时想传的是一个对象的拷贝副本,就要用到copy了。这里的拷贝,有深拷贝和浅拷贝,关于这方面的知识,请看这里:。当我们以关键字copy声明NSArray与NSMutableArray属性成员时,相当于在set方法中以前的直接_array
= array赋值,变成了调用_array = [array copy]进行赋值,这样传入的就是对象拷贝的副本,而不是引用。但是NSMutableArray属性成员以copy声明时,就会出现该属性成员在增删改查时会没有对应的方法。原因就在于copy不论原来的是可变还是不可变,创建的都是不可变副本,而mutablecopy不论原来的是可变还是不可变,创建的都是可变副本。正是这个原因,导致NSMutableArray属性成员在set方法之后变为了不可变的NSArray,当然无法对其进行增删改查了。
1.同时重写属性的get和set方法
在.m中同时重写get和set方法后,总是报错,类似这个样子:后来我通过加上@synthesize array = _array, 当时并不知道为什么会这样,但今天看了下面这个面试题的回答有了明悟,原文如下:
在有了自动合成属性实例变量之后,@synthesize还有哪些使用场景?
回答这个问题前,我们要搞清楚一个问题,什么情况下不会autosynthesis(自动合成)?(实例变量 = 成员变量 = ivar)
同时重写了setter和getter时
重写了只读属性的getter时
使用了@dynamic时
在 @protocol 中定义的所有属性
在 category 中定义的所有属性
重载的属性
当你在子类中重载了父类中的属性,你必须 使用@synthesize来手动合成ivar。
除了后三条,对其他几个我们可以总结出一个规律:当你想手动管理@property的所有内容时,你就会尝试通过实现@property的所有“存取方法”(the accessor methods)或者使用@dynamic来达到这个目的,这时编译器就会认为你打算手动管理@property,于是编译器就禁用了autosynthesis(自动合成)。
因为有了autosynthesis(自动合成),大部分开发者已经习惯不去手动定义ivar,而是依赖于autosynthesis(自动合成),但是一旦你需要使用ivar,而autosynthesis(自动合成)又失效了,如果不去手动定义ivar,那么你就得借助@synthesize来手动合成ivar。
以上已经说的足够明白,所以上面的错误也可以通过手动声明一个_array的成员变量得到解决。
2.用copy关键字声明NSArray与NSMutableArray属性成员的一些问题:
根据iOS里一切皆对象,所以对于对象的赋值都是传一个对象的引用,如果我想在赋值时想传的是一个对象的拷贝副本,就要用到copy了。这里的拷贝,有深拷贝和浅拷贝,关于这方面的知识,请看这里:。当我们以关键字copy声明NSArray与NSMutableArray属性成员时,相当于在set方法中以前的直接_array= array赋值,变成了调用_array = [array copy]进行赋值,这样传入的就是对象拷贝的副本,而不是引用。但是NSMutableArray属性成员以copy声明时,就会出现该属性成员在增删改查时会没有对应的方法。原因就在于copy不论原来的是可变还是不可变,创建的都是不可变副本,而mutablecopy不论原来的是可变还是不可变,创建的都是可变副本。正是这个原因,导致NSMutableArray属性成员在set方法之后变为了不可变的NSArray,当然无法对其进行增删改查了。
相关文章推荐
- set 命令特殊用法
- 批处理中Copy与Xcopy命令的区别小结
- dos 文件复制 copy命令
- GET和post取值限制区别分析
- You must SET PASSWORD before executing this statement的解决方法
- 批处理 Set 命令详解 让你理解set命令第1/2页
- ASP中set与dim的区别(自己的理解)
- 深入C#中get与set的详解
- POST与GET方法的区别简要分析
- sql Set IDENTITY_INSERT的用法
- 谈谈xcopy中的排除copy
- VB使用XMLHTTP实现Post与Get的方法
- 分享下GET和POST的真正区别
- php使用COPY函数更新配置文件的方法
- set_include_path在win和linux下的区别
- ASP.NET的HtmlForm控件学习及Post与Get的区别概述
- asp教程中get post提交表单有5点区别
- 区分ASP.NET中get方法和post方法
- php下通过POST还是GET来传值
- SpringMVC RESTful总结之GET请求