Foundation框架之可变和不可变

------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
上面创建了一个不可变的字符串,当我们给s 重新赋值后,我们通过打印s 的值和地址来测试,此时我们发现s 的值和地址都方法了变化.这说明我们在第二次赋值的时候,在内存中又开辟了一块新的存储空间来存储"fffffff",那么此时并不是字符串"aaaaaaa"发生了变化,而是我们让s  重新指向了另一块内存空间。

        //可变字符串                                               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);

注意事项:
1)用@“hello world”方式创建的字符串,始终是不可变的。
        //创建空得可变字符串
        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
总结:

1)不可变字符串,它的内存空间的大小和存储的内容不能改变
2)可变字符串,它的内存空间的大小和存储的内容可以改变
3)如果把一个不可变字符串强行赋值给一个可变字符串,那么这个可变字符串就变成不可变的

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值