NSMutableString
- “_”方式调用赋值
NSMutableString *mOriginMutableString = [[NSMutableString alloc] initWithString: @"原始数据"];
_mCopyMutableString = mOriginMutableString;
_mStrongMutableString = mOriginMutableString;
_mWeakMutableString = mOriginMutableString;
_mAssignMutableString = mOriginMutableString;
NSLog(@"mOriginMutableString : %p, %@", mOriginMutableString,mOriginMutableString);
NSLog(@"_mCopyMutableString : %p, %@", _mCopyMutableString,_mCopyMutableString);
NSLog(@"_mStrongMutableString: %p, %@", _mStrongMutableString,_mStrongMutableString);
NSLog(@"_mWeakMutableString : %p, %@", _mWeakMutableString,_mWeakMutableString);
NSLog(@"_mAssignMutableString: %p, %@", _mAssignMutableString,_mAssignMutableString);
NSLog(@"引用计数:%@", [mOriginMutableString valueForKey: @"retainCount"]);
运行结果图如下:
有结果图,我们发现,赋值后,引用计数为3,指针相同。
- 通过“self.”的方式调用赋值
self.mCopyMutableString = mOriginMutableString;
self.mStrongMutableString = mOriginMutableString;
self.mWeakMutableString = mOriginMutableString;
self.mAssignMutableString = mOriginMutableString;
结果如图如下:
我们发现引用计数为2了,这是为什么呢?
因为“self.” 会调用getter、setter方法,“_”方式不会调用getter、setter方法,直接访问实例变量并赋值。
strong 指向原来的内存,并且指针数+1,
week 指向原来的内存,并且指针数不变,
assign指向原来的内存,但是指针数不变。
copy来说,如果是self. 调用是深拷贝,重新开辟内存块,修改原来的值,不会导致现有值改变。
如果是_直接访问,则相当于浅拷贝,指向原来的内存,指数+1。修改原来的值,会影响到现有的值。
week 与 assign来说
week内存释放后,指针变为nil
assign内存释放后,指针不为nil,后期数据改变后,出现野指针,导致程序崩溃
retain 与 strong为同样的功能,retain为ARC出现之前的关键字。
增加指针为强引用,不增加指针是弱引用
重新开辟内存块是深拷贝,使用同一个内存块为浅拷贝
NSMutableArray
- 通过“self.”赋值。
NSMutableArray *mOriginMutableArray = [[NSMutableArray alloc] init];
NSMutableString *m1 = [[NSMutableString alloc] initWithString: @"原始数据 1"];
NSMutableString *m2 = [[NSMutableString alloc] initWithString: @"原始数据 2"];
NSMutableString *m3 = [[NSMutableString alloc] initWithString: @"原始数据 3"];
[mOriginMutableArray addObject:m1];
[mOriginMutableArray addObject:m2];
[mOriginMutableArray addObject:m3];
self.mCopyMutableArray = mOriginMutableArray;
self.mStrongMutableArray = mOriginMutableArray;
self.mWeakMutableArray = mOriginMutableArray;
NSLog(@"mOriginMutableArray : %p, %@", mOriginMutableArray,mOriginMutableArray);
NSLog(@"mCopyMutableArray : %p, %@", _mCopyMutableArray,_mCopyMutableArray);
NSLog(@"mStrongMutableArray: %p, %@", _mStrongMutableArray,_mStrongMutableArray);
NSLog(@"mWeakMutableArray : %p, %@", _mWeakMutableArray,_mWeakMutableArray);
NSLog(@"引用计数:%@", [mOriginMutableArray valueForKey: @"retainCount"]);
NSLog(@"%p %p %p %p", &mOriginMutableArray,mOriginMutableArray,mOriginMutableArray[0],mOriginMutableArray[1]);
结果图如下:
- 采用“_”方式调用赋值
_mCopyMutableArray = mOriginMutableArray;
_mStrongMutableArray = mOriginMutableArray;
_mWeakMutableArray = mOriginMutableArray;
结果图如下:
我们发现引用计数减少的原因和上边的一样,即self. 和_ 调用对copy的影响。
NSMutableArray类的addObject方法,对同一个对象执行N次,这这个对象的指针数就会加上N次,所以我们发现,使用_直接调用时,指针数为2,而不是一。
copy同上边的一样,会重新开辟内存区域,strong、weak和原数据指向同一块内存区域,
所以,copy是深拷贝,strong、weak、assign为浅拷贝。
同时,我们修改数组中的元素时,发现,所有的数据元素都变了, 也就是说,数组中的NSMutableString在拷贝时是浅拷贝。
NSString
- “self.”调用
NSString *mOriginString = @"原始数据";
self.mCopyString = mOriginString;
self.mStrongString = mOriginString;
self.mWeakString = mOriginString;
self.mAssignString = mOriginString;
NSLog(@"mOriginMutableString : %p, %@", mOriginString,mOriginString);
NSLog(@"_mCopyMutableString : %p, %@", _mCopyString,_mCopyString);
NSLog(@"_mStrongMutableString: %p, %@", _mStrongString,_mStrongString);
NSLog(@"_mWeakMutableString : %p, %@", _mWeakString,_mWeakString);
NSLog(@"_mAssignMutableString: %p, %@", _mAssignString,_mAssignString);
NSLog(@"引用计数:%@", [mOriginString valueForKey: @"retainCount"]);
NSLog(@"-------------改变值后------------");
mOriginString = @"新值";
NSLog(@"mOriginMutableString : %p, %@", mOriginString,mOriginString);
NSLog(@"_mCopyMutableString : %p, %@", _mCopyString,_mCopyString);
NSLog(@"_mStrongMutableString: %p, %@", _mStrongString,_mStrongString);
NSLog(@"_mWeakMutableString : %p, %@", _mWeakString,_mWeakString);
NSLog(@"_mAssignMutableString: %p, %@", _mAssignString,_mAssignString);
NSLog(@"引用计数:%@", [mOriginString valueForKey: @"retainCount"]);
结果图如下:
2. “_”调用
_mCopyString = mOriginString;
_mStrongString = mOriginString;
_mWeakString = mOriginString;
_mAssignString = mOriginString;
结果图如下:
这个比较好理解,直接说结论了:
NSString 和 NSMutableString 基本相同,除了copy,对NSString来说是浅拷贝,对NSMutableString来说是深拷贝。
同时,我们发现通过self. 和 _ 调用,对copy来说都是一样的,都是浅拷贝。
NSArray
NSString *m1 = @"Origin 1";
NSString *m2 = @"Origin 2";
NSString *m3 = @"Origin 3";
NSArray *mOriginArray = @[m1,m2,m3];
// self.mCopyArray = mOriginArray;
// self.mStrongArray = mOriginArray;
// self.mWeakArray = mOriginArray;
_mCopyArray = mOriginArray;
_mStrongArray = mOriginArray;
_mWeakArray = mOriginArray;
NSLog(@"mOriginArray : %p, %@", mOriginArray,mOriginArray);
NSLog(@"_mCopyArray : %p, %@", _mCopyArray,_mCopyArray);
NSLog(@"_mStrongArray: %p, %@", _mStrongArray,_mStrongArray);
NSLog(@"_mWeakArray : %p, %@", _mWeakArray,_mWeakArray);
NSLog(@"_mWeakArray[0] : %p, %@", mOriginArray[0],mOriginArray[0]);
NSLog(@"引用计数:%@", [mOriginArray valueForKey: @"retainCount"]);
NSLog(@"m1 修改前 : %p, %@", m1,m1);
m1 = @"NEW";
NSLog(@"m1 修改后 : %p, %@", m1,m1);
NSLog(@"_mWeakArray[0] : %p, %@", mOriginArray[0],mOriginArray[0]);
NSLog(@"mOriginArray : %p, %@", mOriginArray,mOriginArray);
NSLog(@"_mCopyArray : %p, %@", _mCopyArray,_mCopyArray);
NSLog(@"_mStrongArray: %p, %@", _mStrongArray,_mStrongArray);
NSLog(@"_mWeakArray : %p, %@", _mWeakArray,_mWeakArray);
NSLog(@"引用计数:%@", [mOriginArray valueForKey: @"retainCount"]);
我们可以发现,NSArray对其赋值时,他是进行的深拷贝,上边的输出,m1虽然后边改为新值了,但是NSArray依然是老值。
在NSArray中,数组本身是浅拷贝。