博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Object-C Block详解
阅读量:2393 次
发布时间:2019-05-10

本文共 2209 字,大约阅读时间需要 7 分钟。

Block简介
Block 是一种比较特殊的数据类型,它可以保存一段代码,在合适的时候取出来调用
ARC
ARC 是 iOS 5推出的新功能,全称叫 ARC(Automatic Reference Counting),就是代码中自动加入了 retain/release,原先需要手动添加的用来处理内存管理的引用计数的代码可以自动地由编译器完成了。该机能在 iOS 5/Mac OS X 10.7 开始导入,利用 Xcode4.2 可以使用该机能。简单地理解ARC,就是通过指定的语法,让编译器(LLVM 3.0)在编译代码时,自动生成实例的引用计数管理部分代码。有一点,ARC并不是GC,它只是一种代码静态分析(Static Analyzer)工具
MRC(Manual Reference Counting : 人工引用计数)
ARC情况下
1> 如果用 copy 修饰 Block,该 Block就会存储在堆空间,则会对Block的内部对象进行强引用,导致循环引用。内存无法释放。
解决方法:
新建一个指针(__weak typeof(Target) weakTarget = Target )指向Block代码块里的对象,然后用weakTarget进行操作,就可以解决循环引用问题
2> 如果用 weak 修饰 Block,该 Block就会存放在栈空间,不会出现循环引用问题
MRC情况下
用copy修饰后,如果要在 Block内部使用对象,则需要进行(__block typeof(Target) blockTarget = Target )处理,在Block里面用blockTarget进行操作
Block的定义格式
返回值类型(^block变量名)(形参列表) = ^(形参列表){
};
调用Block保存的代码
block变量名(实参);
注 : 默认情况下,Block内部不能修改外面的局部变量,Block内部可以修改使用__block修饰的局部变量
Block的模式
1> 无参数无返回值的Block
    /**
     *  void :就是无返回值
     *  emptyBlock:就是该block的名字
     *  ():这里相当于放参数。由于这里是无参数,所以就什么都不写
     */
    void (^emptyBlock)() = ^(){
        NSLog(@"无参数,无返回值的Block");
    };
    emptyBlock();
2> 有参数无返回值的Block
    /**
     *  调用这个block进行两个参数相加
     *
     *  @param int 参数A
     *  @param int 参数B
     *
     *  @return 无返回值
     */
    void (^sumBlock)(int ,int ) = ^(int a,int b){
        NSLog(@"%d + %d = %d",a,b,a+b);
    };
    /**
     *  调用这个sumBlock的Block,得到的结果是20
     */
    sumBlock(10,10);
3> 有参数有返回值的Block
    /**
     *  有参数有返回值
     *
     *  @param NSString 字符串1
     *  @param NSString 字符串2
     *
     *  @return 返回拼接好的字符串3
     */
    NSString* (^logBlock)(NSString *,NSString *) = ^(NSString * str1,NSString *str2){
        return [NSString stringWithFormat:@"%@%@",str1,str2];
    };
    // 调用logBlock,输出的是 我是Block
    NSLog(@"%@", logBlock(@"我是",@"Block"));
Block结合typedef使用
定义一个 Block类型,用定义的类型去创建Block,更加简单便捷
ViewController1 控制器1,ViewController2 控制器2
控制器1 跳转到控制器2,然后在控制器2触发事件回调修改控制器1的block中的信息
ViewController2 目标跳转ViewController
ViewController2.h
#import <UIKit/UIKit.h>
@interface ViewController2 : UIViewController
    typedef void(^changeColor)(id);
    @property (nonatomic, copy) changeColor backgroundColor;
@end
ViewController2.c
self.backgroundColor(@"Test Block");    // 由目标函数调用前一个ViewController中的方法
ViewController1.c
ViewController2 *vc = [[ViewController2 alloc]init];
// 回调修改颜色
vc.backgroundColor = ^(NSString *content){
        NSLog(@"%@", content);
};
[self.navigationController pushViewController:vc animated:YES];

转载地址:http://npgab.baihongyu.com/

你可能感兴趣的文章
强大的g++呢还是强大的C++?太假了吧
查看>>
C++中的内联函数inline总结
查看>>
C++中的函数指针的一些总结
查看>>
ubuntu下为postgresql添加ODBC驱动过程
查看>>
linux下的su,su -,以及cd,cd - ,cd ~总结
查看>>
CAS锁为什么是乐观锁呢
查看>>
Argument of type '(Foo::)(int,int)' does not match 'void (*)(int,int)'以及静态函数问题
查看>>
今天遇到的postgresql中的备份和恢复
查看>>
正好碰到了C++的函数对象,查各路资料,总结写下来吧
查看>>
今天试vi遇到的“Sorry,the command is not available in this version : syntax on”
查看>>
今天又搞到个libDTL.so is not an ELF file - it has the wrong magic bytes at the start.
查看>>
MinGW和vc6中编译DTL的过程
查看>>
Fedora13下为postgresql添加ODBC驱动过程
查看>>
Bridge模式学习
查看>>
Virtual的一些总结
查看>>
Fedora13上折腾了下ACE
查看>>
tomcat keepAliveTimeout=0问题
查看>>
JDK1.6在SUSE11下问题跳变定时任务失效问题记录
查看>>
400 Bad request 一例
查看>>
linux文件锁定
查看>>