版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
【移动应用开发技术】iOS中有哪些常见的修饰词
iOS中有哪些常见的修饰词,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。一、readOnly,readWritereadOnly:根据字面意思,大家都很容易知道是“只读”的意思,意味着只生成了getter方法,而没有生成setter方法,如果这时候调用setter方法,会报一个Assignmenttoreadonlyproperty错误PS:这里顺便说一下self.和_的区别self.就是调用property自动生成的getter和setter方法,而_则是直接去调用实例变量(property会自动生成一个实例变量,如果你重写了getter与setter方法,property自动生成的实例变量就无效了,需要手动去申明一个实例变量或者用@@synthesize).回到正题,那么这意味着我们就完全没办法去修改readOnly的属性了吗?不然,如果你尝试一下setValue:forKey:,你就会发现竟然改变成功了,amazing,让我们来看看代码:@interface
MyFirstClass
:
NSObject
@property
(nonatomic,
copy,
readonly)
NSString
*
string;
@end
#import
"MyFirstClass.h"
@implementation
MyFirstClass
-
(instancetype)
init{
self
=
[super
init];
if
(self)
{
_string
=
@"来改变我啊";
}
return
self;
}
@end
-
(void)viewDidLoad
{
[super
viewDidLoad];
MyFirstClass
*
class
=
[MyFirstClass
new];
NSLog(@"string
===
%@",
class.string);
[class
setValue:@"改变了"
forKey:NSStringFromSelector(@selector(string))];
NSLog(@"string
===
%@",
class.string);
}
Log如下:
2018-03-16
11:08:58.932303+0800
PropertyDesc[5681:445705]
string
===
来改变我啊
2018-03-16
11:08:58.932454+0800
PropertyDesc[5681:445705]
string
===
改变了而如果这个时候在MyFirstClass里加入@implementation
MyFirstClass
-
(instancetype)
init{
self
=
[super
init];
if
(self)
{
_string
=
@"来改变我啊";
}
return
self;
}
+
(BOOL)
accessInstanceVariablesDirectly{
return
NO;
}
@end在运行,boom,系统会报以下错误2018-03-1611:19:21.619747+0800PropertyDesc[6016:478446]***Terminatingappduetouncaughtexception'NSUnknownKeyException',reason:'[<MyFirstClass0x6040000088f0>setValue:forUndefinedKey:]:thisclassisnotkeyvaluecoding-compliantforthekeystring.'2018-03-1611:19:21.619747+0800PropertyDesc[6016:478446]***Terminatingappduetouncaughtexception'NSUnknownKeyException',reason:'[<MyFirstClass0x6040000088f0>setValue:forUndefinedKey:]:thisclassisnotkeyvaluecoding-compliantforthekeystring.'没有找到当前要赋值的属性,那么accessInstanceVariablesDirectly究竟是什么呢,我们打开苹果的官方文档找到Key-ValueCodingProgrammingGuide在这里可以看到,如果这个方法设为YES,访问器就会去寻找名称为_<key>,_is<Key>,<key>,oris<Key>的成员变量,如果为NO,就会跳到第6步,第6步就会报[valueForUndefinedKey:]错误。总结:readOnly并不能完全保证只读,我们可以通过KVC尝试去修改其值。PS:有兴趣的小伙伴可以尝试去修改别人的SDK,包括苹果爸爸的readWrite:这个实在没什么可说的,默认的修饰词就是readWrite,代表可读可写二、nonatomic、atomic我们先看一下官方文档苹果官网对两者的说法atomic:默认的属性修饰词,按官方文档上说即使从不同的线程通过getter或setter方法去访问属性也能完全的获取到或设置值,从这里也可以看出,atomic并不是线程安全的,因为atomic只能保证通过setter和getter方法能获取到一个完整的value,如果A线程在getter,B、C线程在setter,可能A获取到的值是BC执行之后的值,也可能是BC线程执行完之前的值,也可能是BC线程任何一个线程执行完的值。因此atomic的伪代码大概如下:-
(void)setString:(NSString
*)string{
@synchronized(self)
{
if
(_string
!=
string)
{
[_string
release];//MRC
_string
=
[string
copy];
}
}
}
-
(NSString
*)
string{
@synchronized(self)
{
return
_
string;
}
}nonatomic:相对而言,通过nonatomic修饰的属性,并没有做锁的操作,多线程同时进行setter/getter操作,并不能保证得到一个完整的value,所以相对atomic来说nonatomic修饰的属性访问速度更快,而且平时对线程安全我们更倾向于使用信号量、NSLock和synchronized去控制线程安全,他们都能保证代码块的原子性,所以几乎所有的属性都用nonatomic去修饰。三、assign、weak与strongassign:一般来说,我们都用assign去修饰OC的基本数据类型,butwhy?因为assign并不会使对象的引用计数加1,也就是说如果用assign去修饰一个对象,这个对象会立即被释放,重要的是assgin在被释放的时候是不会自动置为nil,还是保留对象的指针地址,会形成野指针,这个时候向其发送消息就会崩溃,简单实验的代码如下:@interface
MySecondClass
:
NSObject
@property
(nonatomic,
assign)
NSMutableArray
*
array;
@end
-
(void)
testMethodTwo{
MySecondClass
*
class
=
[[MySecondClass
alloc]
init];
self.secondClass
=
class;
self.secondClass.array
=
[NSMutableArray
array];
[self.secondClass.array
addObject:@(0)];
}在运行到最后一步的时候程序会崩溃报EXC_BAD_ACCESS的错误,如果打断点的话会发现在执行到这步的时候array还是有地址的。weak:如果把上面的代码@property(nonatomic,assign)NSMutableArray*array;换成@property(nonatomic,weak)NSMutableArray*array;如果把上面的代码@property(nonatomic,assign)NSMutableArray*array;换成@property(nonatomic,weak)NSMutableArray*array;.这个时候程序并不会崩溃,如果你打个断点的话会发现array被自动置为nil,而OC的特性使得像nil发送消息并不会崩溃,这就是weak和assgin最大的区别,此外weak必须用于修饰对象,这和他自动置为nil相关,如果强行使用weak修饰基本数据类型,编译器会报一个大大的红色错误!strong:strong的作用和assign和weak恰恰相反,strong也是属性默认的修饰词,代表着被修饰的对象引用计数+1如果把上面的代码@property(nonatomic,assign)NSMutableArray*array;换成@property(nonatomic,strong)NSMutableArray*array;self.secondClass.array=[NSMutableArrayarray];如果把上面的代码@property(nonatomic,assign)NSMutableArray*array;换成@property(nonatomic,strong)NSMutableArray*array;self.secondClass.array=[NSMutableArrayarray];最后一句代码可以解释为[NSMutableArrayarray]创造了一个对象A,此时A的引用计数为1,self.secondClass.array做为对象B,把A赋值给B的时候,A的引用计数加1,此时A的引用计数为2,B指向了A,然后编译器会自动对A进行释放操作(因为是局部变量),A的引用计数-1。在拥有B的对象不释放的时候,A的引用计数永远不可能为0,除非你手动释放或者把B指向一个新的对象,这样A永远不会被释放,这就是所谓的强引用。weak和strong的区别:weak和strong不同的是当一个对象不再有strong类型的指针指向它的时候它会被释放,即使还有weak型指针指向它。一旦最后一个strong型指针离去,这个对象将被释放,所有剩余的weak型指针都将被清除。copy与retain:copy其实是建立了一个相同的对象,而retain不是.copy是内容拷贝,retain是指针拷贝.copy是内容的拷贝,对于像NSString,的确是这样,如果拷贝的是NSArray这时只是copy了指向array中相对应元素的指针.这便是所谓的"浅复制".atomic是Objc使用的一种线程保护技术,基本上来讲,是防止在写未完成的时候被另外一个线程读取,造成数据错误。而这种机制是耗费系统资源的,所以在iPhone这种小型设备上,如果没有使用多线程间的通讯编程,那么nonatomic是一个非常好的选择。四、copy与mutableCopy苹果官网对对象拷贝的说法在说copy与mutableCopy之前我们先看看官方文档对深拷贝与浅拷贝的阐释,如下深拷贝:对象拷贝-重新申请一片内存保留这个对象,与原对象之间没有半点关系。浅拷贝:指针拷贝-实际上相当于引用计数+1,被拷贝的和拷贝的引用同一个对象。接下来我们分两个方面做测试:1.对非集合类对象的copy操作,以NSString为例对immutableObject做copy操作
NSString
*
string
=
[NSString
stringWithFormat:@"1"];
NSString
*
copyString
=
[string
copy];
NSString
*
mutableCopyString
=
[string
mutableCopy];
NSLog(@"string:%p",
string);
NSLog(@"copyString:%p",
copyString);
NSLog(@"mutableCopyString:%p",
mutableCopyString);Log如下:2018-03-1915:51:38.785253+0800PropertyDesc[10283:759804]string:0xa0000000000003112018-03-1915:51:38.785435+0800PropertyDesc[10283:759804]copyString:0xa0000000000003112018-03-1915:51:38.785518+0800PropertyDesc[10283:759804]mutableCopyString:0x6080000551502018-03-1915:51:38.785253+0800PropertyDesc[10283:759804]string:0xa0000000000003112018-03-1915:51:38.785435+0800PropertyDesc[10283:759804]copyString:0xa0000000000003112018-03-1915:51:38.785518+0800PropertyDesc[10283:759804]mutableCopyString:0x608000055150可以看出对string和copyString的地址是一样的,而mutableCopyString则不同。对mutableObject做copy操作
NSMutableString
*
string
=
[NSMutableString
stringWithFormat:@"1"];
NSString
*
copyString
=
[string
copy];
NSString
*
mutableCopyString
=
[string
mutableCopy];
NSLog(@"string:%p
-
%@",
string,
string);
NSLog(@"copyString:%p
-
%@",
copyString,
copyString);
NSLog(@"mutableCopString:%p
-
%@",
mutableCopyString,
mutableCopyString);
[string
appendString:@",2"];
NSLog(@"copyString:%p
-
%@",
copyString,
copyString);
NSLog(@"mutableCopString:%p
-
%@",
mutableCopyString,
mutableCopyString);Log如下:2018-03-1915:51:38.785670+0800PropertyDesc[10283:759804]string:0x60400005a940-12018-03-1915:51:38.785784+0800PropertyDesc[10283:759804]copyString:0xa000000000000311-12018-03-1915:51:38.785834+0800PropertyDesc[10283:759804]copyString:0xa000000000000311-12018-03-1915:51:38.785891+0800PropertyDesc[10283:759804]mutableCopyString:0x60400005a910-12018-03-1915:51:38.786037+0800PropertyDesc[10283:759804]mutableCopyString:0x60400005a910-12018-03-1915:51:38.785670+0800PropertyDesc[10283:759804]string:0x60400005a940-12018-03-1915:51:38.785784+0800PropertyDesc[10283:759804]copyString:0xa000000000000311-12018-03-1915:51:38.785834+0800PropertyDesc[10283:759804]copyString:0xa000000000000311-12018-03-1915:51:38.785891+0800PropertyDesc[10283:759804]mutableCopyString:0x60400005a910-12018-03-1915:51:38.786037+0800PropertyDesc[10283:759804]mutableCopyString:0x60400005a910-1可以看出对string与copyString、mutableCopyString三者的地址都是不同的。即使改变了原string的value,copyString与mutableCopystring也没有改变,这与下文对集合类对象得出的结论正好相反。结论:对immutableObject进行copy操作是指针拷贝,mutableCopy操作时对象拷贝。对mutableObject进行copy和mutableCopy都是对象拷贝。简单的表格图如下:2.对集合类对象的copy操作对immutableObject做copy操作
NSArray
*
array
=
[NSArray
arrayWithObject:@"1"];
NSArray
*
copyArry
=
[array
copy];
NSMutableArray
*
mutableCopyArray
=
[array
mutableCopy];
NSLog(@"array:%p",
array);
NSLog(@"copyArry:%p",
copyArry);
NSLog(@"mutableCopyArray:%p",
mutableCopyArray);Log如下2018-03-1915:51:38.786167+0800PropertyDesc[10283:759804]array:0x6000000094c02018-03-1915:51:38.786278+0800PropertyDesc[10283:759804]copyArray:0x6000000094c02018-03-1915:51:38.786385+0800PropertyDesc[10283:759804]mutableCopyArray:0x6000002400302018-03-1915:51:38.786167+0800PropertyDesc[10283:759804]array:0x6000000094c02018-03-1915:51:38.786278+0800PropertyDesc[10283:759804]copyArray:0x6000000094c02018-03-1915:51:38.786385+0800PropertyDesc[10283:759804]mutableCopyArray:0x600000240030可以看出array与copyArray的地址是一样的,而mutableCopyArray则不同。对mutableObject做copy操作
NSMutableString
*
string
=
[NSMutableString
stringWithFormat:@"1"];
NSMutableArray
*
array
=
[NSMutableArray
arrayWithObject:string];
NSArray
*
copyArry
=
[array
copy];
NSMutableArray
*
mutableCopyArray
=
[array
mutableCopy];
NSLog(@"array:%p",
array);
NSLog(@"copyArry:%p",
copyArry);
NSLog(@"mutableCopyArray:%p",
mutableCopyArray);
[array
addObject:@"2"];
[string
appendString:@"1"];
NSLog(@"array:%p
-
%@",
array,
array);
NSLog(@"copyArry:%p
-
%@",
copyArry,
copyArry);
NSLog(@"mutableCopArray:%p
-
%@",
mutableCopyArray,
mutableCopyArray);Log如下2018-03-2613:36:38.786499+0800PropertyDesc[10283:759804]array:0x6000002401502018-03-2613:36:38.786600+0800PropertyDesc[10283:759804]copyArry:0x6000000095f02018-03-2613:36:38.786698+0800PropertyDesc[10283:759804]mutableCopyArray:0x6000002400f02018-03-2613:36:38.786865+0800PropertyDesc[10283:759804]array:0x600000240150-(
11,
2)2018-03-2613:36:38.787018+0800PropertyDesc[10283:759804]copyArry:0x6000000095f0-(
11)2018-03-2613:36:38.787142+0800PropertyDesc[10283:759804]mutableCopyArray:0x6000002400f0-(
11)2018-03-2613:36:38.786499+0800PropertyDesc[10283:759804]array:0x6000002401502018-03-2613:36:38.786600+0800PropertyDesc[10283:759804]copyArry:0x6000000095f02018-03-2613:36:38.786698+0800PropertyDesc[10283:7598
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 企业社会责任投资策划合同样本
- 企业食堂管理服务合同模板
- 二手房屋交易合同
- 人力资源招聘助理工作合同
- 产品监制合同书
- 个人收藏品寄存保管协议
- 2024-2030年食醋产业规划专项研究报告
- 2024-2030年预制菜行业市场发展分析及竞争格局研究报告
- 2024-2030年防晒用品项目可行性研究报告
- 2024-2030年金属锻压件市场投资前景分析及供需格局研究预测报告
- 2024年上海市标准房屋租赁合同经典版(三篇)
- 新目标艺术培训中心商业策划书(3篇)
- 辽宁省沈阳市2024-2025学年七年级上学期期中模拟英语试题
- 2024人教版初中八年级数学上册第十四章整式的乘法与因式分解大单元整体教学设计
- 2023年中国铁路国际有限公司招聘考试试题及答案
- 小学高年级课后服务 scratch3.0编程教学设计 二阶课程 项目3数字华容道 第2节 数字块移动教学设计
- 国资国企企业学习二十届三中全会精神专题培训
- 履职工作计划
- 火星营地登陆计划-趣味地产周年庆典市集活动策划方案
- 2024年上海市中考地理试卷(含答案解析)
- 项目工程退出申请书
评论
0/150
提交评论