ARC下block使用情况

ARC与MRC的block有着一些区别,笔记整理ARC的block,仅仅是自己参考的笔记,详情请参考 http://www.cnbluebox.com/?p=255

 

在开始之前,请新建一个Model类,写几个如下的属性,用于后面测试block的特性.

 

 

Block的类型与内存管理

根据Block在内存中的位置分为三种类型NSGlobalBlock,NSStackBlock, NSMallocBlock。

  • NSGlobalBlock:类似函数,位于text段;
  • NSStackBlock:位于栈内存,函数返回后Block将无效;
  • NSMallocBlock:位于堆内存。

 

从打印信息处可以看出,该block是一个__NSGlobalBlock__.

 

虽然只是简单的改了一下,但很明显,刚刚的__NSGlobalBlock__已经变成了__NSMallocBlock__,此处我们可以得知,在处理对象时,block会malloc的.

 

我们使用弱引用集合NSHashTable来验证,一个block的强引用的情况.

#import <Foundation/Foundation.h>

@interface YX_NSHashTable : NSObject

+ (void)add:(id)obj;
+ (BOOL)contain:(id)obj;
+ (NSArray *)allObjs;

@end
#import "YX_NSHashTable.h"

static NSHashTable *table = nil;

@implementation YX_NSHashTable

+ (void)initialize
{
    if (self == [YX_NSHashTable class])
    {
        table = [NSHashTable weakObjectsHashTable];
    }
}

+ (void)add:(id)obj
{
    [table addObject:obj];
}

+ (BOOL)contain:(id)obj
{
    return [table containsObject:obj];
}

+ (NSArray *)allObjs
{
    return [table allObjects];
}

@end

从打印信息还看不出什么东西出来-_-!!

 

将block设置成copy属性后,很明显,还没运行就已经提示了循环引用的问题.

控制器强引用了一个block,而该malloc的block也强引用了控制器.所以,导致了循环引用的问题.

 

堆内存的一个明显的特性就是:他会强引用block中的对象,如果该block被其他不会被释放的东西给强引用了,就会导致循环引用.

 

问:ARC支持dispatch_queue吗?

http://stackoverflow.com/questions/8618632/does-arc-support-dispatch-queues/8619055#8619055

If your deployment target is lower than iOS 6.0 or Mac OS X 10.8

You need to use dispatch_retain and dispatch_release on your queue. ARC does not manage them.

If your deployment target is iOS 6.0 or Mac OS X 10.8 or later

ARC will manage your queue for you. You do not need to (and cannot) use dispatch_retain or dispatch_release if ARC is enabled.

结论:如果你的iOS编译的target是iOS6.0+,ARC支持dispatch_queue.

 

问:如何才能在block中不至于造成泄露呢?

即使是NSMallocBlock也不一定会泄露,但是如果是一个copy属性的block,它一定是NSMallocBlock,这个就需要十分注意.出现在这个block中的对象,是会被这个包含这个block的对象给强引用的.如果这个对象是个单例而不会被释放掉,那就泄露了.

 

问:这种block会导致_model对象泄露吗?

 

 因为block里面出现了对象,这个block变成了NSMallocBlock,理论上,_model会在该block的生命周期中一直被持有.直到它被销毁.

 

问:方法中的block是怎么回事呢?

 

方法中的block是栈block,不用担心会被强引用.

 

问:MRC中的__block与ARC中的__weak有啥联系?

http://stackoverflow.com/questions/7853915/how-do-i-avoid-capturing-self-in-blocks-when-implementing-an-api

The __block keyword marks variables that can be modified inside the block (we're not doing that) but also they are not automatically retained when the block is retained (unless you are using ARC). If you do this, you must be sure that nothing else is going to try to execute the block after the MyDataProcessor instance is released. (Given the structure of your code, that shouldn't be a problem.)Read more about __block.

If you are using ARC, the semantics of __block changes and the reference will be retained, in which case you should declare it__weak instead.

在MRC中, __block 可以让一个变量在 block 中进行修改而不会被这个 block retain.

在ARC中, __weak 才能让一个变量在 block 中不被这个block强引用.

__block是在MRC中使用的.

__weak是在ARC中使用的.

 

时间: 2024-09-08 05:01:23

ARC下block使用情况的相关文章

ARC下的block导致的循环引用问题解析

ARC下的block导致的循环引用问题解析 更详细细节请参考 http://blog.sina.com.cn/s/blog_8c87ba3b0101m599.html   ARC下,copy到堆上的block,会强引用进入到该block中的外部变量.这很容易导致循环引用的问题. 比方说: 一个VC(这里指一个controller)中有一个属性为model.VC强引用了它. VC --> model 这个model呢,里面有一个copy属性的block,该block赋值如下如下.model.dem

ARC中block块作为属性的使用笔记

ARC中block块作为属性的使用笔记 block较难理解,根据在内存中的分布情况就分为3种类型,根据使用的情形又分为很多很多种.虽然用起来容易,但使用不当会造成内存泄露,虽然都是这么说,但你真的研究过为什么会泄露吗?为什么有些时候外部变量进入block的时候会导致引用计数+1呢?   本人做过MRC以及ARC的开发,但大势所趋,ARC将是以后开发的主要模式,即使有MRC也是ARC混编MRC的代码,所以,本文的block的一些使用上的心得都基于ARC的,已经不考虑MRC的了,请看官注意,MRC与

ARC下dealloc过程及.cxx_destruct的探究

ARC下dealloc过程及.cxx_destruct的探究 我是前言 这次探索源自于自己一直以来对ARC的一个疑问,在MRC时代,经常写下面的代码:  1 2 3 4 5 6 7 8 9 - (void)dealloc { self.array = nil; self.string = nil; // ... // // 非Objc对象内存的释放,如CFRelease(...) // ... // [super dealloc]; } 对象析构时将内部其他对象release掉,申请的非Objc

ios开发-ios arc下内存泄露,怎么办?

问题描述 ios arc下内存泄露,怎么办? 对内存递增部分代码加了autorelease 然后把所有self改成weak self 还是没变 是应该将某些参数=nil? 解决方案 http://www.bkjia.com/article/24832.html 解决方案二: iOS ARC 内存泄露问题

iOS6中ARC 下两种释放对象的方法

  使用了 ARC 之后,无疑大大减少了程序员进行内存管理的压力.你再也不用写 release/autorelease 代码了,再也不用写dealloc 方法了.但这不等于程序员不需要内存管理.例如,你需要在 viewDidUnload 方法中对对象进行释放,以防当内存警告发生时,你没有内存可以回收.当然ARC 托管对象的释放方式与 MRC 是不同的.对于 ARC 托管对象,你必须用 ARC 特有的两种释放方式: [self setOjbect:nil]; 或者: self.object=nil

查看Linux下端口占用情况的命令

在使用Linux系统的过程中,有时候会遇到端口被占用而导致服务无法启动的情况.比如HTTP使用80端口,但当启动Apache时,却发现此端口正在使用. 这种情况大多数是由于软件冲突.或者默认端口设置不正确导致的,此时需要查看究竟哪个进程占用了端口,来决定进一步的处理方法.     查看端口占用情况的命令:lsof -i 1 [root@www ~]# lsof -i 2   3 COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME 4 nginx 2333

object-c ARC与block笔记

Avoiding Retain Cycles with __block To avoid retain cycles use __weak , __block id x __block variables are retained under ARC; __block id x;//retains x under ARC manually break cycle by setting __block value to nil; //arc dispatch_block_t getfoo(int

小技巧,关于OC打印指针地址和arc下的retaincount

CFGetRetainCount((__bridge CFTypeRef)self  : 打印retainCount 打印指针的地址(不是指针指向对象的地址):NSLog(@"aStr指针内存地址:%x",&aStr); 打印指针所指向对象的地址使用这个 :NSLog(@"aStr指针所指向对象的地址:%p",aStr);

看朋友日志发现的一个ios下block相关的内存管理问题,很奇怪,请大家帮忙一起来回答!

http://blog.csdn.net/fengsh998/article/details/38090205 这篇文章下面是我的回复,同样的代码只是把变量的定义从局部变量改为类的成员变量就发现了很大的差异,目前还没有找到明确的答案,请大家帮忙看一下!