当用指针指向某个对象时候,可以对其进行管理(通过retain和release)就拥有对这个对象的强引用或弱引用
1、什么是循环引用?
结论:
当两个对象相互持有对方(即拥有对对方的强引用),此时各自的引用计数都为1,释放不了,而造成内存泄露。
当多个对象能形成一个环时候情况类似。
用weak或者__weak创建归零弱引用
因为c指向的地方被释放了,调用它可能会导致问题,如果是weak或者__weak创建的:
2、循环引用发生在什么地方?
相关类之间
如:假如view持有subView时,而subView中有属性为strong修饰的view(会发生循环引用)
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
TestCell *cell =[tableView dequeueReusableCellWithIdentifier:@"UITableViewCellIden" forIndexPath:indexPath];
cell.tableView = tableView;
//这里如果上图属性为strong的话,那么会导致循环引用
return cell;
}
原因分析:
UITableView 是持有 UITableViewcell(引用计数值为1)的,而TestCell继承自UITableViewcell可以看做一个UITableViewcell类型,它对它的类的实例变量(指针,都在堆中)也是持有的,所以属性用strong修饰,那么属性将会对指向的对象持有。如果此时刚好这个对象是UITableView类型,那么就发生了循环引用。
2、易发生在block
如:
//.h文件在ARC
typedef void(^block)(void);
@interface Test : NSObject
@property (nonatomic, copy)block testBlock;
@property (nonatomic, assign)NSInteger temp;
@property (nonatomic, copy)NSString* str;
- (void)inmethod1;
@end
//mian文件在MRC,为了能手动release观察是否发生循环引用。
int main(int argc, char * argv[])
{
Test *test = [[Test alloc]init];
[test inmethod1];
[test release];
NSLog(@"程序即将结束");
}
1、在ARC中(.m文件在ARC中来即测试在ARC中block的影响而导致的循环引用)
分析 :可以看到没有调用dealloc,说明出现了循环引用,那么循环引用怎么产生的呢。
- self 持有 _textblock , _textblock因为通过点方法(setter方法)把inmethod1中的stackblock作copy到了堆上变成了mallocblock,所以_textblock持有mallocblock(修饰符为copy),而在mallocblock中使用了self有关的系列(堆会对self持有)。所以发生了循环引用。
又如果是这样:
分析 :可以看到没有调用dealloc,说明出现了循环引用,那么循环引用怎么产生的呢?而且我们也没有调用setter方法(即没有用到copy修饰的作用)。
- 可以看到这里直接对testBlock进行操作,首先因为self持有_testBlock,而后的block进行了 = 操作ÿ