block

block用来保存一段代码

block的标志:^

block跟函数很像:可以保存代码、有返回值、有形参、调用方式跟调用方法一样

block内部可以访问外面的变量

默认情况下,block内部不能修改外面的局部变量

给局部变量加上__block关键字,这个局部变量就可以在block内部修改

block助记符 inlineBlock

<#returnType#>(^<#blockName#>)(<#parameterTypes#>) = ^(<#parameters#>) {

<#statements#>

};

利用typedef定义block类型

typedef int (^MyBlock)(int, int);

以后就可以利用MyBlock这种类型来定义block变量

MyBlock block;

MyBlock b1, b2;

没有返回值、没有形参的block

int main()
{
// 定义block变量
void (^myblock)() =^(){
NSLog(@"-------");
NSLog(@"-------");
NSLog(@"-------");
}; // 如果block没有形参就可以省略后面的小括号()
void (^llblock)() =^{
NSLog(@"-------");
NSLog(@"-------");
NSLog(@"-------");
}; // 调用block内部代码
myblock();
// 利用block变量调用block内部的代码
llblock(); return ;
}

有形参、有返回值的block

int main()
{ int (^sumblock)(int, int) = ^(int a, int b){
return a + b;
}; int c = sumblock(, ); NSLog(@"%d", c); // 用一个block输出n条横线
void (^lineBlock)(int) = ^(int n)
{
for (int i = ; i<n; i++) {
NSLog(@"----------------");
}
};
lineBlock(); return ;
}

以下是借鉴,拷贝的博文

二、内存位置(ARC情况)

  1、block块的存储位置(block块入口地址):可能存放在2个地方:代码区、堆区(程序分5个区,还有常量区、全局区和栈区,对于MRC情况下代码还可能存在栈区。关于分区详细参考:http://www.cnblogs.com/mddblog/p/4405165.html

  情况1:代码区

  不访问处于栈区的变量(例如局部变量),且不访问处于堆区的变量(例如alloc创建的对象)。也就是说访问全局变量也可以。

/**
没有访问任何变量
*/
int main(int argc, char * argv[]) {
void (^block)(void) = ^{
NSLog(@"===");
};
block();
}
/**
访问了全局(静态)变量
*/
int iVar = 10;
int main(int argc, char * argv[]) {
void (^block)(void) = ^{
NSLog(@"===%d",iVar);
};
block();
}

  情况2:堆区

  如果访问了处于栈区的变量(例如局部变量),或处于堆区的变量(例如alloc创建的对象)。都会存放在堆区。(实际是放在栈区,然后ARC情况下自动又拷贝到堆区)

/**
访问局部变量
*/
int main(int argc, char * argv[]) {
int iVar = 10;
void (^block)(void) = ^{
NSLog(@"===%d",iVar);
};
block();
}

  2、注意事项

  代码存放在堆区时,就需要特别注意,因为堆区不像代码区不变化,堆区是不断变化的(不断创建销毁)。因此代码有可能会被销毁(当没有强指针指向时),如果这时再访问此段代码则会程序崩溃。因此,对于这种情况,我们在定义一个block属性时应指定为strong,或copy:

  @property (nonatomic, strong) void (^myBlock)(void); // 这样就有强指针指向它

  @property (nonatomic, copy)  void (^myBlock)(void);  // 并不会在堆区copy一份,原因见 三

  而对于第1种情况(代码存在代码区),使用strong,copy(不会复制一份到堆区)也可以。因此定义block时最好指定为strong(推荐)或copy。

  3、指定为copy后是否会拷贝一份呢?(或者说是浅拷贝还是深拷贝)

    1 copy可变变量:在赋值指针的同时也会复制指针指向的内存区域。深拷贝,例如NSMutableString对象。

    2 copy不可变变量:等同于strong,还是浅拷贝,例如NSString对象。

因为block是一段代码,即不可变的,所以并不会深拷贝。

Objective-C( block的使用)的更多相关文章

  1. Objective C block背后的黑魔法

    前言 block在Objective C开发中应用非常广泛,我们知道block会捕获外部对象,也知道使用block要防止循环引用. "知其然而不知其所以然"是一件非常痛苦的事情,那 ...

  2. Automake

    Automake是用来根据Makefile.am生成Makefile.in的工具 标准Makefile目标 'make all' Build programs, libraries, document ...

  3. 初学Objective - C语法之代码块(block)

    一.block声明 1.无参数,无返回值: void (^sayHi)(); 2.有参数,有返回值: NSInteger (^operateOfValue)(NSInteger num); block ...

  4. Objective的字符串拼接 似乎没有Swift方便,但也可以制做一些较为方便的写法

    NSString *str1 = @"字符串1"; NSString *str2 = @"字符串2"; //在同样条件下,Objective的字符串拼接 往往只 ...

  5. Objective C ARC 使用及原理

    手把手教你ARC ,里面介绍了ARC的一些特性, 还有将非ARC工程转换成ARC工程的方法 ARC 苹果官方文档 下面用我自己的话介绍一下ARC,并将看文档过程中的疑问和答案写下来.下面有些是翻译,但 ...

  6. iOS Block详细介绍(block实现)

    Block的实现 数据结构定义 block的数据结构定义如下图 对应的结构体定义如下: struct Block_descriptor { unsigned long int reserved; un ...

  7. @weakify, @strongify ObjC的Block中使用weakSelf/strongSelf @weakify/@strongify

    首先要说说什么时候使用weakSelf和strongSelf. 下面引用一篇博客<到底什么时候才需要在ObjC的Block中使用weakSelf/strongSelf>的内容: Objec ...

  8. 堆block和栈block的区分

    0. 问题所在 下面给出一段代码: - (NSArray*) getBlockArray { int num = 916; return [[NSArray alloc] initWithObject ...

  9. ObjC的Block中使用weakSelf/strongSelf @weakify/@strongify

    首先要说说什么时候使用weakSelf和strongSelf. 下面引用一篇博客<到底什么时候才需要在ObjC的Block中使用weakSelf/strongSelf>的内容: Objec ...

随机推荐

  1. 成都PC网站建设需要考虑哪些费用呢

    亿合科技PC建设小编分享下:成都PC网站建设需要考虑哪些费用呢?随互联网的发展,越来越多人想建设自己网站,站长最关心的问题之一就是网站建设需要多少钱.每个网站建设的费用都是不一样的,但是都需要涵盖几个 ...

  2. Openstack的keystone的user-role-list命令的使用

    直接在shell模式下执行 [root@node-5 ~]# keystone user-role-list WARNING: Bypassing authentication using a tok ...

  3. 如何用jquery获取页面下HiddenField的值··

    怎么用jquery获取页面上HiddenField的值·· 怎么用jquery获取页面上HiddenField的值··?HiddenField的值是从后台赋值的··· 先赋值给Hiddenfield ...

  4. mysql出现“SELECT list is not in GROUP BY clause and contains nonaggregated column [duplicate]”错误提示

    项目跨平台时由于mysql设置的问题,原代码运行出现这个错误,此时把mysql设置改下就好了 sql_mode='NO_ENGINE_SUBSTITUTION'

  5. CSS 笔记三(Tables/Box Model/Outline)

    CSS Tables border border: border-width border-style border-color|initial|inherit; border-width borde ...

  6. Orcale与jfinal的添加时间问题

    时间只能不能使用一般的方法进行添加,必须转换,比如添加当前时间,如上图所示

  7. js遍历数组的错误方法

    for (var index in myArray) { // don't actually do this console.log(myArray[index]); } 缺点: 数组的索引值inde ...

  8. h-ui前端框架

    h-ui.net

  9. 设置MySQL自动增长从某个指定的数开始

    自增字段,一定要设置为primary key. 以指定从1000开始为例.1 创建表的时候就设置: CREATE TABLE `Test` ( `ID` int(11) NOT NULL AUTO_I ...

  10. [HIHO1079]离散化(线段树、染色)

    题目链接:http://hihocoder.com/problemset/problem/1079 MD坑爹,线段查询的时候左闭右开.插完挨个点找一遍扔set里,注意没染色的情况. #include ...