block注意事项
1.block的声明和注意事项
#import "ZYViewController.h" @interface ZYViewController () @end /*用typedef可以声明一种类型的block*/ //block前加上typedef, 那么就不是一个block指针(变量),而是一种block类型
//给int (^) (int a, int b) 这种block类型 声明了一个别名,叫做Block5
typedef int (^Block5) (int a, int b); //Block6就是无参无返回的block的类型
typedef void (^Block6) (void); @implementation ZYViewController - (void)viewDidLoad
{
[super viewDidLoad]; //block
//原理:block也是指针,指向的不是对象的内存地址,而是一段代码块的地址 //void/*返回类型*/ (^/*代表是指针类型*/ block1/*变量名*/) (void/*参数*/) = NULL/*初值为空*/; //无参无返回的block,如果无参,参数可以写void,也可以不写
void (^block1) (void) = NULL;
//block1的类型 void (^) (void) 无参无返回的类型
//给block赋值,无参的block赋值,在=后可以写成^(void)、^()、^,如果不是无参的,那么必须把参数类型和形参名写完整
block1 = ^(void) {
NSLog(@"hello world");
};
//执行block
block1(); //有参无返回
//void (^block2) (int)中的(int)只是声明该block参数的个数,以及每个参数的类型,在声明的时候可以不写形式参数,但是在实现的时候必须写形式参数,而且实现时的形式参数名可以和声明时不同
void (^block2) (int n) = ^(int n) {
NSLog(@"------>%d", n);
};
block2(); //多参无返回,每个参数之间用","分割,在执行的时候需要注意参数的顺序
void (^block3) (int age, NSString *name) = ^ (int age, NSString *name) {
NSLog(@"%@今年 %d岁", name, age);
};
block3(, @"龟小妹"); //有参有返回
int (^block4) (int a, int b) = ^(int a, int b) {
return a + b;
};
int sum = block4(, );
NSLog(@"--------->%d", sum); Block5 block5 = NULL;
block5 = ^(int a, int b) {
return a + b;
};
int sum1 = block5(, );
NSLog(@"--------->%d", sum1); //基本数据类型
//1.对于局部的不添加“__block”的基本数据类型,block用到的是对变量的值的拷贝,在block中对变量赋值没用意义
//2.对于局部的添加“__block”的基本数据类型,block中不会对变量的值进行拷贝,可以在block中对变量进行赋值
//3.对于全局基本数据类型的变量,除了作用范围不同外,其他的同添加“__block”的局部变量
__block int num = ;
NSLog(@"地址1----->%p", &num);
void (^block6) (void) = ^(void) {
NSLog(@"1************** %d", num);
NSLog(@"地址2----->%p", &num);
num = ;
};
num = ;
NSLog(@"2**************=== %d", num);
NSLog(@"地址3----->%p", &num);
block6();
NSLog(@"3**************=== %d", num); //指针类型
//1.对于不添加“__block”的局部指针,block中用到的是指针的拷贝,可以用此拷贝的指针去更改对象的属性,但是不能直接更改对象
//2.对于添加“__block”的局部指针,block中不会对指针进行拷贝,可以更改对象
//3.对于全局的指针,除了作用范围外,其他同添加“__block”的局部指针
__block ZYTest *test = [[ZYTest alloc] init];
//NSLog(@"1----->%@---->%p", test, &test);
//NSLog(@"1----->%@", test.date);
void (^block7) (void) = ^(void) {
NSLog(@"2----->%@---->%p", test, &test);
test = [[ZYTest alloc] init];
test.date = [NSDate date];
NSLog(@"2----->%@", test.date);
}; //NSLog(@"3----->%@---->%p", test, &test);
NSLog(@"3----->%@", test.date);
block7();
NSLog(@"4----->%@---->%p", test, &test);
NSLog(@"5----->%@", test.date); }
2.block的内存问题
//1.block变量的copy,不会增加全局的或者是添加“__block”的局部指针的引用计数
//2.block变量的copy,会把不添加“__block”的局部指针指向的对象retain一次
NSDate *date = [NSDate date];
void (^tempBlock) (int n) = ^(int n) {
//NSLog(@"专业测试语句,请勿模仿-->%d", n);
NSLog(@"2---->%d", date.retainCount);
};
block1 = [tempBlock copy];
//block1(50);
//NSLog(@"3---->%d", date.retainCount); self.block2 = ^(void) {
NSLog(@"======专业测试语句,请勿模仿");
}; __block ZYViewController *tempSelf = self;
NSLog(@"1----->self.retainCount=%d", self.retainCount);
void (^block3) (void) = ^(void) {
[tempSelf test];
NSLog(@"2----->self.retainCount=%d", tempSelf.retainCount);
};
self.block2 = block3;
_block2();
NSLog(@"3----->self.retainCount=%d", self.retainCount); #import <UIKit/UIKit.h>
#import "ZYSecViewController.h" @interface ZYViewController : UIViewController
{
//声明一个全局的block,因为block声明在栈上,所以对于全局的block赋值要添加一个copy,把其拷贝到堆上,而且在dealloc中要添加该block的释放语句
void (^block1) (int n);
NSDate *now;
} //采用这种方式也可以声明一个全局的block,自动生成的block变量带一个"_",描述的时候要用copy,如果在其他类中需要使用block作为一个属性,则必须要@property描述
@property(nonatomic, copy)void (^block2) (void);
block注意事项的更多相关文章
- iOS开发--Block
iOS开发--Block 1.什么是Block,block 的作用 ui开发和网络常见功能实现回调,按钮的事件处理方法是回调方法以及网络下载后的回调处理 (1)按钮 target-action 一 ...
- Block编程值得注意的那些事儿
[深入浅出Cocoa]Block编程值得注意的那些事儿 [深入浅出Cocoa]Block编程值得注意的那些事儿 罗朝辉 (http://www.cnblogs.com/kesalin/) 本文遵循 ...
- Block编程注意的问题
一,前言 block 是在 iOS 4 中引入的新特性,它和 C++ 11 中的 lamba 表达式概念相似,有时候也被称为闭包.经过一段时间的使用,我发现要用对用好 block 还是有不少需要注 ...
- block知识总结
一.block在内存中存在的形式 1.当把block句法写在函数或者方法外面时,系统会在静态数据区分配一块内存区域给block对象.这片区域在程序执行期会一直存在. 2.当block句法写在函数或者方 ...
- OC-ARC,类扩展,block
总结 标号 主题 内容 一 autorelease autorelease基本概念/自动释放池/autorelease基本使用 二 autorelease注意事项 注意点/应用场景 三 ARC 什么是 ...
- iOSDay27之界面通信
1. 属性传值(前面的界面给后面传值) 第一步: 在 SecondViewController.h 文件里定义一个存放传过来值的变量 contents #import <UIKit/UIKit. ...
- OC基础(19)
类扩展(Class Extension) Block基本概念 typedef和Block Block注意事项 *:first-child { margin-top: 0 !important; } b ...
- OC基础笔记目录
OC基础(1) Objective-C简介 OC和C对比 第一个OC程序 面向对象思想 OC基础(2) 类与对象 类的设计 第一个OC类 对象方法的声明和实现 类方法的声明和实现 OC基础(3) 对象 ...
- LintCode——Pour Water
Pour Water: We are given an elevation map, heights[i] representing the height of the terrain at that ...
随机推荐
- [转]JVM系列一:JVM内存组成及分配
原文地址:http://www.cnblogs.com/redcreen/archive/2011/05/04/2036387.html JVM系列一:JVM内存组成及分配 java内存组成介绍:堆( ...
- SQL Server阻塞的检查
1. 阻塞 除了内存.CPU.I/O这些系统资源以外,阻塞和死锁是影响数据库应用性能的另一大因素. 所谓的「阻塞」,是指当一个数据库会话中的事务,正在锁定其他会话事务想要读取或修改的资源,造成这些 ...
- Event事件、进程池与线程池、协程
目录 Event事件 进程池与线程池 多线程爬取梨视频 协程 协程目的 gevent TCP服务端socket套接字实现协程 Event事件 用来控制线程的执行 出现e.wait(),就会把这个线程设 ...
- GIL全局解释器锁、死锁、递归锁、线程队列
目录 GIL全局解释锁 多线程的作用 测试计算密集型 IO密集型 死锁现象 递归锁 信号量(了解) 线程队列 GIL全局解释锁 GIL本质上是一个互斥锁. GIL是为了阻止同一个进程内多个进程同时执行 ...
- redis 进程使用root用户启动 -- 整改方案
最近内部风险整改, 各种进程使用root身份进行启动不符合要求, 于是各路神仙各施其法,为的就是让 某进程不以root 启动: 先以 redis 为例: 原有进程如下: #超一流标准的执行文件位置及配 ...
- Shel脚本-初步入门之《06》
Shel脚本-初步入门-06 Shell 脚本的建立和执行 6.Shell 脚本的建立和执行 6.1 Shell脚本的建立 在 Linux 系统中,Shell 脚本(bash Shell 程序)通常是 ...
- 运行输出时候遇到了Json.Disosi@3fa77460格式·
比如我的运行输出时候遇到了Json.Disosi@3fa77460这种类路径+@+储存空间编码格式 发现是实体类忘记加了toString方法 使用ALT+ins快捷键点击toString()方法 再运 ...
- OpenGL实例:纹理映射
OpenGL实例:纹理映射 作者:凯鲁嘎吉 - 博客园 http://www.cnblogs.com/kailugaji/ 更多请查看:计算机图形学 1. 介绍 用于指定一维.二维和三维纹理的函数分别 ...
- Vue移动端报错[Intervention] Unable to preventDefault inside passive event listener due to target being treated as passive.
解决方法如下 项目方案: 在最外侧添加样式操作 .
- 蓝桥杯dfs搜索专题
2018激光样式 #include<bits/stdc++.h> using namespace std; /* dfs(i) 第i个激光机器 有两种选择:vis[i-1] == 0 时 ...