1.第一种情况(常量区赋值)
@property(nonatomic,strong)NSString* string1;
@property(nonatomic,strong)NSString* string2;
self.string1= @“1”;
self.string2=self.string1;
self.string1 =nil;
NSLog(@"sting1的地址:%p string2的地址:%p string1:%@ string2:%@",self.string1,self.string2,self.string1,self.string2);
Guess that what would you see ?
You will see...
sting1的地址:0x0 string2的地址:0x106f16ad0 string1:(null) string2:1
why ?
当你对字符串赋值时,他们共同指向常量区的@“1”的地址
2.第二种情况(开辟空间,并强引用)
OK,you know the first kind of circumstance,know we will see the second kind of circumstance.
和第一种情况基本一样,只是修改把@“1”改为NSString * str = [[NSString alloc]initWithFormat:@"1"];
@property(nonatomic,strong)NSString* string1;
@property(nonatomic,strong)NSString*string2;
NSString * str = [[NSString alloc]initWithFormat:@"1"];
self.string1= str;
self.string2=self.string1;
self.string1 =nil;
NSLog(@"sting1的地址:%p string2的地址:%p string1:%@ string2:%@",self.string1,self.string2,self.string1,self.string2);
Guess that what would you see ?
may be you think , oh it must be different .But it is the same.
sting1的地址:0x0 string2的地址:0x7fc5b9e14f70 string1:(null) string2:1
这次我们开辟了空间,string1和string2都指向了一块内存,因为string1和string2都是强引用类型,所以都对这块内存保有一份,引用计数加1,当string1为nil时,引用计数减1,但是string2还保有一份,所以这块内存并未释放。
3.第三种情况(开辟空间,弱引用)
和第二种情况基本一样,只是修改把string2改为弱引用,为了效果明显,我们再加一句str = nil;
@property(nonatomic,strong)NSString* string1;
@property(nonatomic,weak)NSString*string2;
NSString * str = [[NSString alloc]initWithFormat:@"1"];
self.string1= str;
self.string2=self.string1;
self.string1 =nil;
str = nil;
NSLog(@"sting1的地址:%p string2的地址:%p string1:%@ string2:%@",self.string1,self.string2,self.string1,self.string2);
sting1的地址:0x0 string2的地址:0x0 string1:(null) string2:(null)
这就是弱引用,当string1 = nil时,str还保有一份内存,但是当str=nil时,由于string2是weak(弱引用),所以并没有持有一份内存,所以这块内存就被释放了,string2指向的那块内存都被释放了,string2就被置为nil.
总结:
1.strong:持有一份内存,引用计数加1,当一块内存所有的strong都释放了对自己的引用,(开辟空间的也释放了)引用计数为0,这块内存就被释放了.
2.weak :对内存的引用没有影响,它只是单方面的指向一块内存,并不持有,若它指向的内存释放了,它就会自动置空(nil).
3.常量区的赋值,对引用计数没有影响,这块内存不是你来释放,所以其他引用改变对你没有影响.