------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
学习过OC的都应该知道,在OC中有一个单词 “Mutable”,它的意思是可变的。
那什么是可变,什么是不可变呢?
首先先了解一下什么是Foundation框架
Foundation框架是IOS/MAC中其他框架的基础,Foundation类层次的根是NSObject类,它(和NSObject及NSCopying协议一起)定义了基本的对象属性和行为。Foundation框架的剩余部分由几组相互关联的类和一些独立的类组成。有一些代表基本数据类型的类,如字符串、字节数组、用于存储其它对象的集合类;一些代表系统信息的类,如日期类;还有一些代表系统实体的类,比如端口、线程、和进程。
如何使用Foundation框架
直接引用头文件即可,是不是很简单。
#import <Foundation/Foundation.h>
接下来我们来看看在Foundation框架中有哪些常见的可变和不可变,
NSString———————————————>NSMutableString
NSArray———————————————>NSMutableArray
NSDictionary—————————————>NSMutableDictionary
NSString是OC中核心处理字符串的类之一,它是一个类。
NSMutableString类,继承了NSString类,它可以使用NSString类的所有方法。
NSString是不可变的,里边的文字内容是不能改变的。
NSMutableString是可变的,它可以任意的在字符串中添加,删除,和插入字符。
字符串的可变和不可变
不可变:指的是字符串在内存中占用的存储空间固定,并且存储的内容不能发生变化。
可变:指的是字符串在内存中占据的存储空间可以不固定,并且存储的内容可以被修改。
//不可变字符串
NSString *s = @"aaaaaaa";
NSLog(@"%@\t%p",s,s); //aaaaaaa 0x100001048
//给s赋值一个新值
s = @"fffffff";
NSLog(@"%@\t%p",s,s); //fffffff 0x100001088
//可变字符串 012345678
NSMutableString *s1 = [NSMutableString stringWithFormat:@"bbcedbbb"];
NSLog(@"%@\t%p",s1,s1); //bbcedbbb 0x100200390
//调用可变字符串的appendString方法
[s1 appendString:@"cccccccc"];
NSLog(@"%@\t%p",s1,s1); //bbcedbbbcccccccc 0x100200390
//调用可变字符串的deleteCharactersInRange方法
[s1 deleteCharactersInRange:NSMakeRange(2, 3)];
NSLog(@"%@\t%p",s1,s1); //bbbbbcccccccc 0x100200390
//插入一个字符串
[s1 insertString:@"chengxuyuan" atIndex:2];
//0123456789..............
NSLog(@"%@\t%p",s1,s1); //bbchengxuyuanbbbcccccccc 0x100200390
//替换字符串
[s1 replaceCharactersInRange:NSMakeRange(7, 4) withString:@"#$%*"];
NSLog(@"%@\t%p",s1,s1); //bbcheng#$%*anbbbcccccccc 0x100200390
上面创建了一个可变字符串 s1的 ,此时我们调用 s1 的 appendString、deleteCharactersInRange、insertString、replaceCharactersInRange等方法进行操作,我们还是通过打印字符串的值和地址来比较,此时我们发现在操作结束后,s1 的值发生了变化,但是地址没有变。地址没有变,就是说我们对字符串的插入、修改、删除、替换的操作都是在修改同一块内存空间,也就是 s1 所指向的空间。
//创建空得可变字符串
NSMutableString *s2 = [NSMutableString string];
NSLog(@"%@\t%p",s2,s2);
注意事项:
//创建空得可变字符串
NSMutableString *s2 = [NSMutableString string];
//此处有警告: Incompatible pointer types assigning to 'NSMutableString *' from 'NSString *'
s2 = @"person";
NSLog(@"%@\t%p",s2,s2); //person 0x100001130
在我们强行赋值后可以打印出来值,但是编译器或报一个警报。那么接下来修改s2的值
<span style="font-size:14px;"> [s2 appendString:@"dog"];
NSLog(@"%@\t%p",s2,s2);</span>
此时程序运行到[s2 appendString:@"dog"]; 这句代码时报错
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Attempt to mutate immutable object with appendString:'
*** First throw call stack:
(
0 CoreFoundation 0x00007fff8b1a064c __exceptionPreprocess + 172
1 libobjc.A.dylib 0x00007fff8c88f76e objc_exception_throw + 43
2 CoreFoundation 0x00007fff8b1a04fd +[NSException raise:format:] + 205
3 CoreFoundation 0x00007fff8b15ddee mutateError + 110
4 Mutable 0x0000000100000dfe main + 766
5 libdyld.dylib 0x00007fff9561c5c9 start + 1
6 ??? 0x0000000000000001 0x0 + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
事实证明,即使我们把不可变字符串强行赋值给可变的字符串后,该字符串还是不可变,我们无法对其进行修改等操作。2)NSMutableString的String,会覆盖掉原来所有字符串。
NSMutableString *s3 = [NSMutableString stringWithFormat:@"ddddddddddddd"];
NSLog(@"%@\t%p",s3,s3);
//调用s3的String属性
s3.string = @"aaaaaa"; //ddddddddddddd 0x100400000
NSLog(@"%@\t%p",s3,s3); //aaaaaa 0x100400000
总结: