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注意事项的更多相关文章

  1. iOS开发--Block

    iOS开发--Block 1.什么是Block,block 的作用 ui开发和网络常见功能实现回调,按钮的事件处理方法是回调方法以及网络下载后的回调处理 (1)按钮 target-action   一 ...

  2. Block编程值得注意的那些事儿

    [深入浅出Cocoa]Block编程值得注意的那些事儿   [深入浅出Cocoa]Block编程值得注意的那些事儿 罗朝辉 (http://www.cnblogs.com/kesalin/) 本文遵循 ...

  3. Block编程注意的问题

    一,前言   block 是在 iOS 4 中引入的新特性,它和 C++ 11 中的 lamba 表达式概念相似,有时候也被称为闭包.经过一段时间的使用,我发现要用对用好 block 还是有不少需要注 ...

  4. block知识总结

    一.block在内存中存在的形式 1.当把block句法写在函数或者方法外面时,系统会在静态数据区分配一块内存区域给block对象.这片区域在程序执行期会一直存在. 2.当block句法写在函数或者方 ...

  5. OC-ARC,类扩展,block

    总结 标号 主题 内容 一 autorelease autorelease基本概念/自动释放池/autorelease基本使用 二 autorelease注意事项 注意点/应用场景 三 ARC 什么是 ...

  6. iOSDay27之界面通信

    1. 属性传值(前面的界面给后面传值) 第一步: 在 SecondViewController.h 文件里定义一个存放传过来值的变量 contents #import <UIKit/UIKit. ...

  7. OC基础(19)

    类扩展(Class Extension) Block基本概念 typedef和Block Block注意事项 *:first-child { margin-top: 0 !important; } b ...

  8. OC基础笔记目录

    OC基础(1) Objective-C简介 OC和C对比 第一个OC程序 面向对象思想 OC基础(2) 类与对象 类的设计 第一个OC类 对象方法的声明和实现 类方法的声明和实现 OC基础(3) 对象 ...

  9. LintCode——Pour Water

    Pour Water: We are given an elevation map, heights[i] representing the height of the terrain at that ...

随机推荐

  1. [转]JVM系列一:JVM内存组成及分配

    原文地址:http://www.cnblogs.com/redcreen/archive/2011/05/04/2036387.html JVM系列一:JVM内存组成及分配 java内存组成介绍:堆( ...

  2. SQL Server阻塞的检查

    1. 阻塞   除了内存.CPU.I/O这些系统资源以外,阻塞和死锁是影响数据库应用性能的另一大因素. 所谓的「阻塞」,是指当一个数据库会话中的事务,正在锁定其他会话事务想要读取或修改的资源,造成这些 ...

  3. Event事件、进程池与线程池、协程

    目录 Event事件 进程池与线程池 多线程爬取梨视频 协程 协程目的 gevent TCP服务端socket套接字实现协程 Event事件 用来控制线程的执行 出现e.wait(),就会把这个线程设 ...

  4. GIL全局解释器锁、死锁、递归锁、线程队列

    目录 GIL全局解释锁 多线程的作用 测试计算密集型 IO密集型 死锁现象 递归锁 信号量(了解) 线程队列 GIL全局解释锁 GIL本质上是一个互斥锁. GIL是为了阻止同一个进程内多个进程同时执行 ...

  5. redis 进程使用root用户启动 -- 整改方案

    最近内部风险整改, 各种进程使用root身份进行启动不符合要求, 于是各路神仙各施其法,为的就是让 某进程不以root 启动: 先以 redis 为例: 原有进程如下: #超一流标准的执行文件位置及配 ...

  6. Shel脚本-初步入门之《06》

    Shel脚本-初步入门-06 Shell 脚本的建立和执行 6.Shell 脚本的建立和执行 6.1 Shell脚本的建立 在 Linux 系统中,Shell 脚本(bash Shell 程序)通常是 ...

  7. 运行输出时候遇到了Json.Disosi@3fa77460格式·

    比如我的运行输出时候遇到了Json.Disosi@3fa77460这种类路径+@+储存空间编码格式 发现是实体类忘记加了toString方法 使用ALT+ins快捷键点击toString()方法 再运 ...

  8. OpenGL实例:纹理映射

    OpenGL实例:纹理映射 作者:凯鲁嘎吉 - 博客园 http://www.cnblogs.com/kailugaji/ 更多请查看:计算机图形学 1. 介绍 用于指定一维.二维和三维纹理的函数分别 ...

  9. Vue移动端报错[Intervention] Unable to preventDefault inside passive event listener due to target being treated as passive.

    解决方法如下 项目方案: 在最外侧添加样式操作 .

  10. 蓝桥杯dfs搜索专题

    2018激光样式 #include<bits/stdc++.h> using namespace std; /* dfs(i) 第i个激光机器 有两种选择:vis[i-1] == 0 时 ...