block 对外部引用变量的处理

一、静态变量 和 全局变量 以及 可变对象(NSMutableArray,NSMutableString)的变量

在加和不加  __block 都会直接引用变量地址。也就意味着 可以修改变量的值。在没有加__block 参数的情况下。

以下所有block 均为

=<__NSStackBlock__: 0x7fff5829e9c0> 栈block ,且 MRC 环境。

    NSMutableArray *mutableArray = [[NSMutableArray alloc] initWithObjects:@"asfd", nil];
    NSMutableString *metableStr = [NSMutableString stringWithString:@"metableStr"] ;

    void (^print)(void) = ^{
        [mutableArray addObject:@"haha"];
        [metableStr appendString:@"_hello"];
        NSLog(@"=array========%ld====%@",[mutableArray retainCount],mutableArray);
        NSLog(@"=metableStr=======%@", metableStr);

    }
    [metableStr appendString:@"_hello_"];
    [mutableArray addObject:@"sdfsfdsf"];
    NSLog(@"======%@",print);

    print();

打印内容是: block 内

=array========1====(

asfd,

sdfsfdsf,

haha

)

=metableStr=======metableStr_hello__hello

二, 常量变量(NSString *a = @"hello";a 为常量变量,@“hello”为常量。)-----不加__block类型 block 会引用常量的地址(浅拷贝)。加__block类型 block会去引用常量变量(如:a变量,a = @"abc".可以任意修改a 指向的内容。)的地址。

如果不加__block 直接在block 内部修改变量 ,会编译报错。block 内部改变量是 只读的。

但是 就一定可以推断  block 会深拷贝 该变量吗???

对于常量 @“hello”  存储在 内存中的常量区, 程序结束才会释放 内存。  如:

NSString *str = @"hello";

NSString *abcStr = @"hello";

编译器会优化处理, str 和 abcStr 都会指向 常量区的@“hello” 地址。

    NSString *str = @"hello";
    void (^print)(void) = ^{
        NSLog(@"block=str======%p",str);
    }
     str = @"hello1";
    print();

block 会拷贝变量内容到自己的栈内存上,以便执行时可以调用。 但并不是对str 内容做了深拷贝,重新申请内存。

因为str 是栈内存上的变量,指向 一个常量区的@“hello”. 编译器做的优化是   当block 去拷贝str 指向内容时发现是个常量,

所以会去引用 @“hello” 的指针,没必要再取申请一块内存。

复习下内存分类:    http://blog.csdn.net/u011848617/article/details/39346075

时间: 2024-10-12 11:20:14

block 对外部引用变量的处理的相关文章

IOS开发—block对外部变量的内存管理

block对外部变量的内存管理 代码块在ios中通常用于回调,本文主要介绍block对外部变量的管理机制.我们知道如果要在block中使用block外面的变量,如果该变量是局部变量,就要先将其申明为__block类型.为什么呢?这就涉及到block对外部变量的内存管理. 一.基本数据类型 先看下面测试代码: //局部变量 - (void)localDataTest { int localData = 100; NSLog(@"localData --%p",&localData

block的内存分析,循环引用,变量访问,数据结构定义

一.block的内存分析 如上图: 定义了一个weak的block,那么它在内存中的表现形式如右下角, 1.没有对block进行copy操作,而是weak,block就存储在栈空间中. 2.如果block存储于栈空间,不会对block内部所用到的对象产生强引用. 如上图: 对block进行了一次copy操作,如果对block进行copy操作,block就会存储到堆空间当中. 1.如果block存储于堆空间,就会对block内部所用到的对象产生强引用. 2.如下图所示,就会产生循环引用,造成P对象

block循环引用

block里边会有循环引用的风险,它可能对外部一个变量出现强引用,所以需要判断里边是否有循环引用,通过dealloc方法(销毁当前控制器.或销毁要测试的变量),判断是否循环引用.主要在block 里边出现self 的时候一定要注意,看看self里边的属性是不是强引用. BLOCK ***************  ************** * viewcontroller   *<-----------------------------  * downimg  * ************

iOS Block循环引用

前言 本篇文章精讲iOS开发中使用Block时一定要注意内存管理问题,很容易造成循环引用.本篇文章的目标是帮助大家快速掌握使用block的技巧. 我相信大家都觉得使用block给开发带来了多大的便利,但是有很多开发者对block内存管理掌握得不够好,导致经常出现循环引用的问题.对于新手来说,出现循环引用时,是很难去查找的,因此通过Leaks不一定能检测出来,更重要的还是要靠自己的分析来推断出来. 声景一:Controller之间block传值 现在,我们声明两个控制器类,一个叫ViewContr

Block的引用循环问题 (ARC &amp; non-ARC)

Block实现原理 首先探究下Block的实现原理,由于Objective-C是C语言的超集,既然OC中的NSObject对象其实是由C语言的struct+isa指针实现的,那么Block的内部实现估计也一样,以下三篇Blog对Block的实现机制做了详细研究: A look inside blocks: Episode 1 A look inside blocks: Episode 2 A look inside blocks: Episode 3 虽然实现细节看着头痛,不过发现Block果然

block 解析 - 静态变量

静态变量 上一篇 我们了解了block全局变量的使用,静态变量和全局变量一样,可以直接在block内部使用,也可以在block内部修改 引用官方文档: Global variables are accessible, including static variables that exist within the enclosing lexical scope. 我们来看一段代码: 声明一个静态变量,在block内部修改 static NSString * _para1; -(void )tes

block 解析 - 成员变量

成员变量 在 上一篇 中我们讲了截获变量特性,对于局部变量,变量不加__block修饰符,在block内部是无法修改变量的值,而且初始化block之后,对变量修改,就无法同步到block内部,但是对于成员变量,结果却不一样,即时不加__block修饰符,block初始化后,对于block内部引用的变量的修改,也能同步到block内部,并且在block内部可以修改成员变量的值. Demo: 声明两个变量:_person2._p1 @interface KDBlockTest() { NSStrin

【少年,放松~】出现block循环引用的三种情况和处理办法

刚入职在看已经上线的项目,其中用到block进行快捷回调的做法很常用,但是Xcode都给给以了如下[循环引用]的警告(如下)的情况,结合网络上的查找和自己的理解,进行总结如下. // Capturing 'self' strongly in this block is likely to lead to a retain cycle 出现这种情况的原因主要是:因为block的特性,声明block的对象都会以copy的形式持有block,而block对于它内部的对象也会进行强引用,从而导致了循环引

【转】block强弱引用

原地址:Block内的强引用 众所周知,当某个对象持有着一个Block的时候,如果在Block内部使用强引用反过来持有这个对象,就会导致引用循环.为了避免引用循环,可以使用__weak修饰符,苹果的官方文档在用代码演示__weak修饰符的时候,有这么一个例子: 那么,myController持有着completionHander,在completionHander内部又用一个strongMyController反过来去持有myController,这不也是一个引用循环吗?为了探究这个问题,可以用