Objective-C之Block

简介:

Block基本概念

本小节知识点:

  1. 【了解】什么是Block
  2. 【理解】block的格式

1.什么是Block

  • Block是iOS中一种比较特殊的数据类型

  • Block是苹果官方特别推荐使用的数据类型, 应用场景比较广泛

    • 动画
    • 多线程
    • 集合遍历
    • 网络请求回调
  • Block的作用

    • 用来保存某一段代码, 可以在恰当的时间再取出来调用
    • 功能类似于函数和方法

2.block的格式

  • Block的定义格式
返回值类型 (^block变量名)(形参列表) = ^(形参列表) {

};
  • block最简单形式
void (^block名)() = ^{代码块;}

例如:
void (^myBlock)() = ^{ NSLog(@"李南江"); };
  • block带有参数的block的定义和赋值
void (^block名称)(参数列表)
= ^ (参数列表) { // 代码实现; }

例如:
void (^myBlock)(int) = ^(int num){ NSLog(@"num = %i", num); };
  • 带有参数和返回值的block
返回类型 (^block名称)(参数列表)
= ^ (参数列表) { // 代码实现; }

例如:
int (^myBlock)(int, int) = ^(int num1, int num2){ return num1 + num2; };
  • 调用Block保存的代码
block变量名(实参);

block和typedef的使用

C语言的指向函数指针用法

#import <Foundation/Foundation.h>

int sum(int value1,int value2)
{
 return value1 + value2;
}
int minus(int value1,int value2)
{
 return value1 - value2;
}
int main(int argc,onst char * argv[])
{
 int (*sumP)(int,int);
 sumP = sum;
 NSLog(@"sum = %i",sumP(20,10));
 
 int (*minusP)(int,int)
 minusP = minus;
 NSLog(@"minus = %i",minusP(20,10));
 
 return 0;
}

由于相同的部分可以抽离出来,所以需要使用typedef

#import <Foundation/Foundation.h>

int sum(int value1,int value2)
{
 return value1 + value2;
}
int minus(int value1,int value2)
{
 return value1 - value2;
}

typedef int (*calculte)(int,int)

int main(int argc,onst char * argv[])
{
 calculte sumP = sum;
 NSLog(@"sum = %i",sumP(20,10));
 
 calculte minusP = minus;
 NSLog(@"minus = %i",minusP(20,10));
 
 return 0;
}

OC的block的用法

#import <Foundation/Foundation.h>

int main(int argc,onst char * argv[])
{
 int (^sumBlock)(int,int);
 sumBlock = ^(int value1,int value2){
 return value1 + value2;
 };
 NSLog(@"sum = %i",sumBlock(20,10));
 
 int (^minBlock)(int,int);
 minBlock = ^(int value1,int value2){
 return value1 - value2;
 };
 NSLog(@"min = %i",minBlock(20,10));
 
 return 0;
}

使用typedef之后:

#import <Foundation/Foundation.h>

typedef int (^calculteBlock)(int,int);

int main(int argc,onst char * argv[])
{
 calculteBlock sumBlock = ^(int value1,int value2){
 return value1 + value2;
 };
 NSLog(@"sum = %i",sumBlock(20,10));
 
 calculteBlock minBlock = ^(int value1,int value2){
 return value1 - value2;
 };
 NSLog(@"min = %i",minBlock(20,10));
 
 return 0;
}

block的应用场景

在学习UI之后就会体会到block的好处。

这段代码要多练习,练习到不用看源码就能熟练敲出来。

#import <Foundation/Foundation.h>

void Hello(void (^func)())
{
 NSLog(@"Hello Wrold~");
 func();
 NSLog(@"Hello HeYang~");
}


void sayHello()
{
 Hello(^{
 NSLog(@"Hello World,Hello HeYang~");
 });
}

int main(int argc, const char * argv[]) {
 @autoreleasepool {
 sayHello();
 }
 return 0;
}

举个block应用实例场景:

需求:
 找到需要读取并需要操作的文件
步骤:
 读取文件
 操作文件
 关闭文件
分析:
 其中读取文件和关闭文件都是一样的
 而操作文件,会根据需求而变化,或者根据文件类型而不一样
总结:
 这里就需要使用block把操作文件的功能分离出来。

将Objc的m文件编译成C++文件的终端命令:

cc -rewrote-objc xx.m(OC的m文件)

然后在当前目录下就会出现后缀cpp的C++文件。

block是存储在堆中还是在栈中?
默认情况下block存储在栈中,如果对block进行一个copy操作,block会转移到堆中
如果block在栈中,block中访问了外界的对象,那么不会对对象进行retain操作
但如果是block在堆中,block中访问了外界的对象,那么会对外界的对象进行一次retain

在MRC模式下,我们分析一下是不是会出现内存泄露

Person *p = [[Person alloc]init];
NSLog(@"retainCount = %lu",[p retainCount]);
void (^myBlock)() = ^{
 NSLog(@"a = %@",p);
 NSLog(@"block retainCount = %lu",[p retain]);
}
Block_copy(myBlock);

myBlock();

如果在block中访问了外界的对象,一定要给对象加上__block,只要加上了__block,哪怕block在堆中,也不会对外界的对象进行retain。

加了__block就是地址传递,不加__block是值传递。正因为是值传递,所以可以访问其值,或者return返回其值。


相关文章
|
Java 程序员 C语言
Objective-C之Block、GCD好文章推荐
Objective-C之Block、GCD好文章推荐
166 0
|
iOS开发 Swift
Objective-C编程 - 关于Block的要点
1. 首先,我们快速过一下,什么是Block? Block是一段代码,它在OC中以^开头,可以有返回值,和参数列表,但就是没有名字。 所以,你可以把它认为是匿名函数。 事实上,它和Swift中的闭包(Closure)是一样的。
1040 0
|
iOS开发 Java 网络安全
Objective-C语法之代码块(block)的使用
<p style="margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px; font-family:Arial; font-size:14px; line-height:26px"> 代码块本质上是和其他变量类似。不同的是,代码块存储的数据是一个函数体。使用代码块是,你可以像调用其他标准函数一样,传入
1122 0