block底层实现原理

1、关于block的循环引用:

block属性,一般用copy修饰;

1.1.如果没有对block进行copy操作,block就存储于栈空间

1.2.如果对block进行copy操作,block就存储于堆空间---强引用

1.3.如果block存储于栈空间,不会对block内部所用到的对象产生强引用

1.4.如果block存储于堆空间,就会对block内部所用到的对象产生强引用

注意1:由于使用了copy修饰,如果block中调用了block属性的对象,就会造成循环引用

为了避免循环引用,需要对对象进行若引用修饰:

1 ICKPerson *p = [[ICKPerson alloc] init];
2 // 1、修饰方法1
3     //    __unsafe_unretained typeof(p) weakP = p;
4 // 2、修饰方法2
5     __block typeof(p) weakP = p;
6     p.testBlock = ^{
7         [weakP run];
8     };

2、关于block中变量的值:

2.1  如果变量没有通过__block修饰,那么block中的变量本质是值捕获,在创建block的同时,是将变量的值传入到block中,无论什么时候调用,变量的值就是最初传进去的值

1  int age = 10;
2  void (^block)() = ^{ // 值捕获
3    NSLog(@"age=%d", age);// 打印是10;
4  };
5  age = 20;
6  block();

2.2  如果变量通过__block修饰,那么block中的变量实际传递的是变量的地址,在创建block的同时,是将变量的地址传入到block中,在调用block的时候,其变量的值是当时变量的值(通过地址(指针)获取到)。

1 __block int age = 1;
2  void (^block)() = ^{ // 值捕获
3         NSLog(@"age=%d", age);// 打印是20;
4   };
5     age = 20;
6     block();

3、关于block的内部实现:

创建block的时候,内部是创建了对应的函数;

        在调用block的时候,是调用了之前封装的函数。

4、关于block的应用:

4.1.如何定义block

 1  1、// inline
 2      // blockName:block变量名
 3      // 返回值类型(^变量名)(返回值类型)
 4      <#returnType#>(^blockName)(<#parameterTypes#>) = ^(<#parameters#>) {
 5      <#statements#>
 6      };
 7 void(^block)() = ^(){
 8         NSLog(@"block");
 9     };
10  2、// name:Block类型别名
11 typedef void(^MyBlock)()
12  MyBlock myBlock = ^(){
13   };

4.2、调用block

1  block();
2  myBlock();

4.3、实战练习:

// 4.通讯录Block使用:

// 点击保存,通知联系人刷新表格,用代理

// block:小弟 代理:打电话

// block:先把刷新表格的代码保存起来

// 等用户点击了保存按钮的时候,调用Block

4.3.1、在头文件中(向其他文件中传递数据的文件)定义一个block:是否带参数,根据需求确定

1 @class ICKAddViewController,ICKContact;
2 typedef void(^ICKAddViewControllerBlock)(ICKContact *contact);
3 @interface ICKAddViewController : UIViewController
4 @property (nonatomic, strong) ICKAddViewControllerBlock contactBlock;
5 @end

4.3.2、在获取数据后,跳转页面之前,调用block,将数据传递过去

1 - (IBAction)addcontact {
2     ICKContact *contact = [ICKContact contactWithName:self.nameFiled.text andPhone:self.phoneFiled.text];
3     // 调用block
4     if (self.contactBlock) {
5         self.contactBlock(contact);
6     }
7     [self.navigationController popViewControllerAnimated:YES];
8 }

4.3.3、在获取(保存、利用)数据的文件中(拿到获取数据的对象的时候)调用其block属性,保存block代码段(实现特定功能的代码)

 1 // 跳转控制器时数据传递
 2 - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
 3     ICKAddViewController *addVc = segue.destinationViewController;
 4     // 声明block
 5     addVc.contactBlock = ^(ICKContact *contact){
 6         [self.contacts addObject:contact];
 7
 8         // 存储数据
 9         NSString *cache = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)[0];
10         NSString *path = [cache stringByAppendingString:@"contacts.data"];
11         [NSKeyedArchiver archiveRootObject:self.contacts toFile:path];
12         [self.tableView reloadData];
13     };
14 }
时间: 2024-08-03 21:14:48

block底层实现原理的相关文章

iOS OC语言: Block底层实现原理

来源http://www.wtoutiao.com/p/11dgbk4.html 先来简单介绍一下Block Block是什么? 苹果推荐的类型,效率高,在运行中保存代码.用来封装和保存代码,有点像函数,Block可以在任何时候执行. Block和函数的相似性:(1)可以保存代码(2)有返回值(3)有形参(4)调用方式一样. Block 底层实现 定义一个简单的block 我们再给a赋值为20,此时打印出来a 的值还是10 但当我们在第一次给a 赋值时,前面加上__block 的时候,则打印出来

Java并发编程系列-(8) JMM和底层实现原理

8. JMM和底层实现原理 8.1 线程间的通信与同步 线程之间的通信 线程的通信是指线程之间以何种机制来交换信息.在编程中,线程之间的通信机制有两种,共享内存和消息传递. 在共享内存的并发模型里,线程之间共享程序的公共状态,线程之间通过写-读内存中的公共状态来隐式进行通信,典型的共享内存通信方式就是通过共享对象进行通信. 在消息传递的并发模型里,线程之间没有公共状态,线程之间必须通过明确的发送消息来显式进行通信,在java中典型的消息传递方式就是wait()和notify(). 线程之间的同步

迭代器Iterator的底层实现原理

第一步:没有接口的迭代器简单实现原理 1 package com.bjsxt.xiaofei; 2 /** 3 * 迭代器底层原理 4 * 方法: 5 * hasNext() 6 * next() 7 * remove() 8 * @ClassName: MyAarryList 9 * @Description: TODO(这里用一句话描述这个类的作用) 10 * @author 尚晓飞 11 * @date 2014-7-29 下午7:06:09 12 * 13 */ 14 public cl

浅议事件异步处理底层实现原理

//主类 package cn.com.likeshow.bluetoothchat; import android.os.Bundle; import android.app.Activity; import android.view.Menu; import android.widget.LinearLayout; import android.widget.TextView; public class MainActivity extends Activity { @Override pr

由PHP底层工作原理说起

之前做过.net,java开发,也写过几个Php的网站,似乎3种主要编程语言都接触了.但是越来越觉得自己对编程的整个流程缺乏一个整体的认识,尤其是底层的机制.譬如网络编程,编译原理,服务器端,数据库存储引擎原理等.于是看了一些书,比较经典的有apue,unp,tcp/ip,nginx,mysql的innodb存储引擎,深入理解jvm.渐渐发现无论用什么语言做开发,背后都有linux,shell,c/c++,nginx服务器,mysql的身影.也许只有掌握了这些核心的原理知识,一个程序员才具有核心

block底层

block基础使用语法 Block 语法: 1.作为当地变量: returnType (^blockName)(parameterTypes) = ^returnType(parameters) { ... ... } 2.作为属性: @property (nonatomic,copy) returnType (^blockName)(parameterTypes) 3.作为方法参数: -(void)someMethodThatTakesABlock:( returnType (^)(param

那些年读过的书《Java并发编程的艺术》一、并发编程的挑战和并发机制的底层实现原理

一.并发编程的挑战 1.上下文切换 (1)上下文切换的问题 在处理器上提供了强大的并行性就使得程序的并发成为了可能.处理器通过给不同的线程分配不同的时间片以实现线程执行的自动调度和切换,实现了程序并行的假象. 在单线程中:线程保存串行的执行,线程间的上下文切换不会造成很大的性能开销. 而在多线程中:线程之间频繁的调度需要进行上下文切换以保存当前执行线程的上下文信息和加载将要执行线程的上下文信息,而上下文切换时需要底层处理器.操作系统.Java虚拟机提供支持的会消耗很多的性能开 销.如果频繁的进行

PHP底层工作原理

分类: PHP本质2011-11-15 15:55 2840人阅读 评论(0) 收藏 举报 php工作apacheextensionzendvariables 目录(?)[+] 简介 先看看下面这个过程: 我们从未手动开启过PHP的相关进程,它是随着Apache的启动而运行的: PHP通过mod_php5.so模块和Apache相连(具体说来是SAPI,即服务器应用程序编程接口): PHP总共有三个模块:内核.Zend引擎.以及扩展层: PHP内核用来处理请求.文件流.错误处理等相关操作: Ze

【java并发编程艺术学习】(三)第二章 java并发机制的底层实现原理 学习记录(一) volatile

章节介绍 这一章节主要学习java并发机制的底层实现原理.主要学习volatile.synchronized和原子操作的实现原理.Java中的大部分容器和框架都依赖于此. Java代码 ==经过编译==>Java字节码 ==通过类加载器==>JVM(jvm执行字节码)==转化为汇编指令==>CPU上执行. Java中使用的并发机制依赖于JVM的实现和CPU的指令. volatile初探 volatile是是轻量级的synchronized,它在多处理器开发中保证了共享变量的可见性.可见性