最近学习iOS。项目开发过程中使用可变数据类型但没有alloc开辟内存,造成赋值不成功,在这里顺便总结一下Objective-C中的(不)可变类型:
一:不可变数据类型
拿NSString为例说明一下
NSString *str = @"Tom";
str = @"Rose";
简单的画了一个图描述一下,我们都知道NSString是复杂数据类型,因此他的数据内容是存放在堆中的。变量str是存放在栈中的,str存放的是堆中的地址,即区域A的地址。
当 str = @"Rose";
时他实际上并没有在原来的区域A上改变内容Tom为Rose,而是在堆中新开辟出来区域B存放Rose,同时将栈中str变量存放的区域A地址转换成区域B的地址。综上所述,NSString改变的是地址而不是内容,因此NSString是不可变类型。
二:可变数据类型
拿NSMutableArray为例说明一下
NSMutableArray *arr;
arr = [[NSMutableArray alloc] init];
[arr addObject:@"Rose"];
NSLog(@"数组: %@", arr); // 输出(Rose)
简单的画了一张图描述一下,首先声明可变类型的数组arr,并在堆中开辟一块内存区域,因为内部值的数量大小并没有确定,因此他开辟的是一个范围区域。使用方法addObject
将Rose添加进去实际上是将Rose添加到这块区域内部。如果再添加一个Tom他也是在堆中已经开辟的这块区域内部添加Tom。他没有改变地址改变的是内容,因此被称为可变类型。
三:可变类型要初始化堆内存空间
两段代码区分一下
NSString *str;
str = @"Jack";
NSLog(@"str 是:, %@", str); // 输出Jack
NSMutableArray *arr;
[arr addObject:@"Rose"];
NSLog(@"数组: %@", arr); // 输出null
分析:第一段代码中不可变类型的NSString的赋值和开辟空间是同步进行的,因此他的赋值是成功的。而对于可变类型NSMutableArray来说使用方法addObject
增加对象的前提必须是已经有了开辟好的堆内存,因此在第二段代码中必须要增加开辟内存步骤,否则是add不进去的。
方法一:
NSMutableArray *arr;
arr = [[NSMutableArray alloc] init];
方法二:
NSMutableArray *arr = [NSMutableArray array];
在实际开发中万万不可忘记初始化开辟内存!!