zoukankan      html  css  js  c++  java
  • IOS开发--网络篇-->Block 简介

    1、Blocks简介

    Block字面意思就是代码块 iOS4.0、Mac OS X 10.6开始Apple引入的特性

    Block是Objective C语言中的对象 但是与NSObject有所区别 Block是特殊的Objective C对象

    Block 对象提供了一个使用 C 语言和 C 派生语言(如 Objective-C 和 C++)来创建表达式作为一个特别的函数。在其他语言和环境中,一个block对象有时候被称为“闭包(closure)”。在这里,它们通常被口语化为”块(blocks)”,除非在某些范围它们容易和标准 C 表达式的块代码混淆。

    对于闭包(closure),有很多定义,其中闭包就是能够读取其它函数内部变量的函数

    “^”符号可以称为caret ['kærət] 也叫脱字符 插入符 

    返回值(^块对象名称)(参数列表类型) = ^(参数列表){块对象中的代码}

    2、用处

    1)简单的回调过程,不用再实现并调用某个函数 (UIView动画)

    2)代码简洁,减少冗余代码

    3)与GCD结合使用 爽爆了 

    使用:UIView动画、presentViewController、ASI 

    3、声明和创建Block

    声明Block引用 无参无返回 无参有返回 有参无返回 有参有返回

    定义Block

    使用Block

    typedef声明 简称typedef 为现有类型创建一个新的名字,或称为类型别名,在结构体定义,还有一些数组等地方都会用到 

    返回值或参数为Block的

    snippet 代码片段

    4、Block对变量存取管理

    1)局部变量

    局部变量,在Block中只读。Block定义时copy变量的值,在Block中作为常量使用,所以即使变量的值在Block外改变,也不影响它在Block中的值

     

    2)__Block修饰的变量

    如果要在block内修改block外声明的局部变量,那么一定要对该变量加__block标记

     

    3)Static修饰符的或全局变量

    因为全局变量或静态变量在内存中的地址是固定的Block在读取该变量值的时候是直接从其所在内存读出,获取到的是最新值,而不是在定义时copy的常量.

     Block变量,被__Block修饰的变量称作Block变量基本类型的Block变量等效于全局变量或静态变量 但对象的block变量不会

    5、Block的内存管理

    非ARC下

    Block是默认建立在栈上, 所以如果离开方法作用域, Block就会被丢弃

    Block的copy、retain、release操作  不同于NSObject的copy、retain、release操作:

    只要实现一个对周围变量没有引用的Block,就会显示为是NSGlobalBlock

    如果其中加入了对局部变量的引用,就是NSStackBlock

    如果你对一个NSStackBlock对象使用了Block_copy()或者发送了copy消息,就会得到NSMallocBlock

     

    1)NSGlobalBlock:retain、copy、release操作都无效

    2)NSStackBlock:retain、release操作无效,必须注意的是,NSStackBlock在函数返回后,Block内存将被回收,即使retain也没用。

    容易犯的错误是[mutableAarry addObject:stackBlock],(补:在ARC中不用担心此问题,因为ARC中会默认将实例化的Block拷贝到堆上)在函数出栈后,从mutableAarry中取到的stackBlock已经被回收,变成了野指针

    正确的做法是先将[stackBlock copy]到堆上,然后加入数组:[mutableAarry addObject:[[stackBlock copy] autorelease]]。支持copy,copy之后生成新的NSMallocBlock类型对象。

    3)NSMallocBlock支持retain、release,虽然retainCount始终是1,但内存管理器中仍然会增加、减少计数。copy之后不会生成新的对象,只是增加了一次引用,类似retain;

    4)Block_copy与copy等效,Block_release与release等效

    5)对Block不管是retain、copy、release都不会改变引用计数retainCount,retainCount始终是1

    6)尽量不要对Block使用retain操作,不方便管理。

    Block的使用:UIView动画、presentViewController、ASI

     

    6、Block对objc对象的内存管理

    staticObj、globalObj、instanceObj、localObj、blockObj多种类型obj对象

    主要是block被copy时其块中用到的变量的引用计数

    1)非ARC

    globalObj和staticObj在内存中的位置是确定的所以Block copy时引用计数不会改变

    instanceObj在Block copy时并没有直接让instanceObj对象本身引用计数加1,但却让self引用计数加1。所以在Block中可以直接读写instanceObj变量。 

    localObj在Block copy时,系统自动增加其引用计数

    blockObj在Block copy时,引用计数也不会改变

    使用__block避免循环引用 __block 类 *对象 = self

     

    void(^block)(void)= ^{

    [blockSelf doSomething];

    };

     

    7、循环引用retain cycle

    循环引用指两个对象相互强引用了对方,即retain了对方,从而导致谁也释放不了谁的内存泄露问题。如声明一个delegate时一般用assign而不能用retain或strong,因为你一旦那么做了,很大可能引起循环引用

     

    释放second 在fist delloc中释放 fist的delloc什么时候执行呢 ?

    fist引用计数为0时执行 ,然而现在即便是将fist从window.rootViewController上卸载下来 即释放一次 却发现second还保留着first的一次引用 到头来还是要释放second 形成了delegate版本的retain cycle 即循环引用

     

    释放_pBlock 在viewController delloc中释放 delloc什么时候执行呢?

    viewController引用计数为0时执行 ,然而现在即便是将viewController从window.rootViewController上卸载下来 即释放一次 却发现_pBlock还保留着viewController的一次引用 到头来还是要释放_pBlock 形成了block版本的retain cycle 即循环引用

    Block的内存管理

    ARC下

    在ARC下, 以下几种情况, Block会自动被从栈复制到堆:

    1.被执行copy方法

    2.作为方法返回值

    3.将Block赋值给附有__strong修饰符的id类型的类或者Blcok类型成员变量时

    4.在方法名中含有usingBlock的Cocoa框架方法或者GDC的API中传递的时候.

    Block中的对象的内存管理

    ARC下

    只有在使用local变量时,block会复制指针,且强引用指针指向的对象一次。其它如全局变量、static变量、block变量等,block不会拷贝指针,只会强引用指针指向的对象一次。

    block的循环引用,因为block在拷贝到堆上的时候,会retain其引用的外部变量,那么如果block中如果引用了它的宿主对象,那很有可能引起循环引用。如:self.myblock = ^{[self doSomething];};

    使用__weak避免循环引用

    Tips:

    内存主要分为

    1.栈 - 由编译器自动分配释放  里面的变量通常是局部变量 函数参数等

    2.堆 - 一般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收 alloc

    3.全局区(静态区 static),全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。- 程序结束释放 static

    People *p;  People *p2 = nil;

    4.另外还有一个专门放常量的地方。- 程序结束释放  NSString *lastName = @“xue”;

    lastName = @“dkjs”;

    5、方法区

  • 相关阅读:
    HDU 5585 Numbers
    HDU 3308 LCIS
    POJ 2991 Crane
    POJ 1436 Horizontally Visible Segments
    POJ 3667 Hotel
    HaiHongOJ 1003 God Wang
    【SDOI 2008】 递归数列
    5月19日省中提高组题解
    【HDU 1588】 Gauss Fibonacci
    【POJ 3233】Matrix Power Series
  • 原文地址:https://www.cnblogs.com/gegeboke/p/4324671.html
Copyright © 2011-2022 走看看