循环引用在ARC下和在MRC下都会出现问题


问题描述:  两个对象互相引用,导致他们的引用计数都为1,就会造成不会被释放


ARC下:两个对象一个使用 weak修饰,一个使用strong

MRC下:两个对象一个使用retain修饰,一个使用assign


文件1


<span style="font-size:18px;">#import <Foundation/Foundation.h>

@class Dog;
@interface Person : NSObject
//@property (nonatomic,strong) Dog *dog;
//解决循环引用的问题:把对象一端设置为weak弱引用
@property (nonatomic,weak) Dog *dog;
@end
@implementation Person
-(void)dealloc{
NSLog(@"Person is dealloc");
}
@end</span>


文件2

<pre name="code" class="objc"><span style="font-size:18px;">#import <Foundation/Foundation.h></span>



@class Person;
@interface Dog : NSObject
@property (nonatomic,strong) Person *owner;
@end
@implementation Dog
-(void)dealloc{
NSLog(@"Dog is dealloc");
}
@end




文件3


#import "Person.h"
#import "Dog.h"
int main(){
@autoreleasepool{
//局部变量的声明周期:
//从定义的位置开始,到它所在的代码“}”结束
Person *person = [Person new];
Dog *dog = [Dog new];

//问题:这句话会引起释放吗?
//答:会,它是在该函数执行完释放
p.dog = dog;


//1.如果两个对象相互引用,那么两个对象都不会被释放
//2.如果只有上面一个对象引用另一个对象,则两对象都会被释放
//3.解决方法:把对象的一段改成weak修饰,弱指针
dog.owner = p;

}
return 0;
}







@property在ARC机制下 和 在MRC机制下的比较

1.  nonatomic            nonatomic

2.  atomic                  atomic

3.  readwrite              readwrite

4.  readonly               readonly

5.  assign                  assign

6.  strong                  retain

7.  weak                   assign


8.  copy                   copy




ARC的使用特点及注意事项

1.ARC特点总结
 (1) 不允许调用 release ,retain ,retainCount
 (2) 允许重写dealloc ,但是不允许调用[super dealloc]
 (3) @property参数:
         strong: 相当于原来的retain(适用于OC对象类型),成员变量是强指针
weak  : 相当于原来的assign,(适用于OC对象类型),成员变量是弱指针
assign: 适用于非OC对象类型(基础类型)
  

2.ARC使用注意事项
  (1) ARC中,只要弱指针指向的对象不存在了,就直接吧弱指针做清空(赋值nil)操作
  (2)  __weak Person *p = [[Person alloc] init]; 
        不合理,对象一创建出来就被释放掉,ARC会把指针设置为nil
        即使此时我们使用p调用eat方法,那么它也不会报错,因为执行的是[nil eat]
  (3) 如果换成是弱指针,则换成weak,不需要加__