• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

《Programming with Objective-C》第八章 Working with Blocks

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

 

Block语法——无参数版本

定义(Block的值)

^{
    NSLog(@"This is a block");
}

 

声明

void (^simpleBlock)(void);

类似int i;

 

赋值

simpleBlock = ^{
    NSLog(@"This is a block");    
}

类似i = 2;

 

声明的时候定义

void (^simpleBlock)(void) = ^{
    NSLog(@"This is a block");
}

类似int i = 2;

 

调用

simpleBlock();

 

Block语法——带参数版本

定义

^(double firstValue, double secondValue)
{
    return firstValue * secondValue;
}

or

^double (double firstValue, double secondValue) 
{
    return firstValue * secondValue;
}

 

声明

double (^multiplyTwoValues)(double, double);

 

赋值

multiplyTwoValues = ^(double firstValue, double secondValue) 
{
    return firstValue * secondValue;
};

 

声明的时候定义

double (^multiplyTwoValues)(double, double) =
^(double firstValue, double secondValue) 
{
    return firstValue * secondValue;
};

 

调用

double result = multiplyTwoValues(2,3);

 

__block修饰符

int anInteger = 42;

void (^testBlock)(void) = ^{    //此时只是Block定义,并没有执行里面的函数
    NSLog(@"Integer is: %i", anInteger);
};

anInteger = 84;

testBlock();    //Block调用 输出42

 

Value is captured when the block is defined.

Block定义的时候,将值复制一份给自己,所以该值已经不受外界影响。

 

__block int anInteger = 42;

void (^testBlock)(void) = ^{    //此时只是Block定义,并没有执行里面的函数
    NSLog(@"Integer is: %i", anInteger);    
};

anInteger = 84;

testBlock();    //Block调用 输出84

 

Because anInteger is declared as a __block variable, its storage is shared with the block declaration.

此时Block里面的值与外面的值共享同一份内存

 

Block与self的恩怨情仇

It’s important to take care when capturing self because it’s easy to create a strong reference cycle when capturing self.

 

因为变量默认是__strong修饰(详见这里),所以要时刻注意在block里面对self的引用(只要出现了self关键字就算引用了,因为block会自动capture)

假如self里面定义了一个block,那么self有一个指向block的strong指针(比如该block是self的一个strong成员变量);假如block里面使用了self,则block也默认拷贝了一个指向self的strong指针,此时形成strong reference cycle.

解决方法:在Block前面创建一个__weak类型的指向self的指针,并在block里面使用该指针。

例子

__weak typeof(self) weakSelf = self;    //学习下这种写法哦 typeof(self)
self.simpleBlock = ^{
    [weakSelf f];
};
...
self.simpleBlock();

但是,假如Block里面又有一个Block,怎么办?最好是强引用weakSelf,此时strongSelf强引用的是weakSelf而不是self,所以不会形成strong reference cycle

__weak typeof(self) weakSelf = self;    //学习下这种写法哦 typeof(self)
self.simpleBlock = ^{
    [weakSelf f];
    __strong typeof(weakSelf) strongSelf = weakSelf;
    self.simpleBlock2 = ^{
        [strongSelf f];
    };
    self.simpleBlock2();
};
...
self.simpleBlock();

图解

一个函数最好只有一个Block参数,且最好是在最后一个

A Block Should Always Be the Last Argument to a Method.

It’s best practice to use only one block argument to a method.

 

使用typedef定义一个block

typedef int (^Sum)(int, int);
Sum mySum = ^(int a, int b){
    return a+b;
}

or

typedef void (^XYZSimpleBlock)(void);
@property (copy) XYZSimpleBlock blockProperty;

 

使用copy修饰block的property

@property (nonatomic, copy) Sum mySum;
@property (nonatomic, copy) void (^blockProperty)(void);

非ARC下就必须写copy,because a block needs to be copied to keep track of its captured state outside of the original scope
在ARC下写不写copy都无所谓,so it's a best practice to set copy property for block whether it's ARC or not.

 


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
Builder(Chapter 6 of Pro Objective-C Design Patterns for iOS)发布时间:2022-07-12
下一篇:
Objective-C桥接模式--简单实用和说明发布时间:2022-07-12
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap