ios block使用

循环引用

£可爱£侵袭症+ 提交于 2020-03-12 07:40:33
ARC已经出来很久了,自动释放内存的确很方便,但是并非绝对安全绝对不会产生内存泄露。导致iOS对象无法按预期释放的一个无形杀手是——循环引用。循环引用可以简单理解为A引用了B,而B又引用了A,双方都同时保持对方的一个引用,导致任何时候引用计数都不为0,始终无法释放。若当前对象是一个ViewController,则在dismiss或者pop之后其dealloc无法被调用,在频繁的push或者present之后内存暴增,然后APP就duang地挂了。下面列举我们变成中比较容易碰到的三种循环引用的情形。 (1)计时器NSTimer 一方面,NSTimer经常会被作为某个类的成员变量,而NSTimer初始化时要指定self为target,容易造成循环引用。 另一方面,若timer一直处于validate的状态,则其引用计数将始终大于0。先看一段NSTimer使用的例子(ARC模式): 1 #import <Foundation/Foundation.h> 2 @interface Friend : NSObject 3 - (void)cleanTimer; 4 @end 1 #import "Friend.h" 2 @interface Friend () 3 { 4 NSTimer *_timer; 5 } 6 @end 7 8 @implementation Friend 9 -

iOS block详解

99封情书 提交于 2020-03-08 18:49:04
文章目录 概述 Block的定义与使用 实际开发中的定义 block与外界变量 截获自动变量(局部变量)值 默认情况 __block修饰的外部变量 Block的copy操作 Block的存储域及copy操作 __block变量与__forwarding 防止Block循环引用 Block的使用示例 Block作为变量(Xcode快捷键:inlineBlock) Block作为属性(Xcode快捷键:typedefBlock) 作为OC中的方法参数 block回调 概述 Block的定义与使用 //1.无参数,无返回值,声明和定义 void ( ^ MyBlockOne ) ( void ) = ^ ( void ) { NSLog ( @"无参数,无返回值" ) ; } ; MyBlockOne ( ) ; //block的调用 //2.有参数,无返回值,声明和定义 void ( ^ MyblockTwo ) ( int a ) = ^ ( int a ) { NSLog ( @"a=%d我就是block,有参数,无返回值" , a ) ; } ; MyblockTwo ( 100 ) ; //3.有参数,有返回值 int ( ^ MyBlockThree ) ( int , int ) = ^ ( int a , int b ) { NSLog ( @"%d我就是block

iOS消息机制

落爺英雄遲暮 提交于 2020-03-05 03:24:26
每个应用程序或多或少,都由一些松耦合的对象构成,这些对象彼此之间要想很好的完成任务,就需要进行消息传递。 一下是所有可用的消息传递机制: Core Data managed object context是notification的发送者,而获取这些notification的主体则是接收者。一个滑块(slider)是action消息的发送者,而在代码里面对应着实现这个action的responder就是接收者。对象中的某个属性支持KVO,那么谁修改这个值,谁就是发送者,对应的观察者(observer)则是接收者。 KVO KVO提供了这样一种机制:当对象中的某个属性值发生了改变,可以对这些值的观察者做出通知。KVO的实现包含在Foundation里面,基于Foundation构建的许多Framework对KVO都有所依赖。如果对某个对象中值的改变情况感兴趣,那么可以使用KVO消息传递机制。这里有两个要求,首先,接收者(会接收到值发生改变的消息)必须知道发送者(值将发生改变的那个对象)。另外,接收者同样还需要知道发送者的生命周期,因为在销毁发送者对象之前,需要取消观察者的注册。如果这两个要求都满足了,消息传递过程中可以是1对多(多个观察者可以注册某个对象中的值)。如果计划在Core Data对象上使用KVO,需要知道这跟一般的KVO使用方法有点不同。那就是必须结合Core

ios-常见的循环引用

柔情痞子 提交于 2020-03-01 19:12:54
介绍: 循环引用,指的是多个对象相互引用时,使得引用形成一个环形,导致外部无法真正是否掉这块环形内存。其实有点类似死锁。 举个例子:A->B->C->....->X->B ->表示强引用,这样的B的引用计数就是2,假如A被系统释放了,理论上A会自动减小A所引用的资源,就是B,那么这时候B的引用计数就变成了1,所有B无法被释放,然而A已经被释放了,所有B的内存部分就肯定无法再释放再重新利用这部分内存空间了,导致内存泄漏。 情况一:delegate Delegate是ios中开发中最常遇到的循环引用,一般在声明delegate的时候都要使用弱引用weak或者assign @property (nonatomic, weak, nullable) id <UITableViewDelegate> delegate; 当然怎么选择使用assign还是weak,MRC的话只能用assign,在ARC的情况下最好使用weak,因为weak修饰的变量在是否后自动为指向nil,防止不安全的野指针存在 情况二:Block Block也是比较常见的循环引用问题,在Block中使用了self容易出现循环引用,因此很多人在使用block的时候,加入里面有用到self的操作都会声明一个__weak来修饰self。其实便不是这样的,不是所有使用了Block都会出现Self循环引用问题

iOS -- block

梦想与她 提交于 2020-02-15 10:42:54
Block:一种匿名函数,可以捕获周围的变量 Block是一种匿名函数,Block中可以保存一段代码,它可以作为参数、作为返回值,在需要的时候调用。常用于GCD、动画、各种回调 block 在实现时就会对它引用到的它所在方法中定义的局部变量进行一次只读(const)拷贝,然后在 block 块内使用该只读拷贝 NSString * functionName = @"functionName"; NSString * (^testBlock)(NSString *) = ^NSString * (NSString * name){ myName = @"nana"; // functionName = @"fff"; //报错,不能改变自动变量的值 self.vcName = @"vvvvv"; //没有报错,可以改变变量的值 NSLog(@"%@",name); return name; }; testBlock(@"cc"); 如果想要在block里改变局部变量的值,可以用 __block 修饰符 __block int val = 10; void (^blk)(void) = ^{printf("val=%d\n",val);}; val = 2; blk(); 在Block定义时便是将局部变量的值传给Block变量所指向的结构体

iOS block

落花浮王杯 提交于 2020-02-10 07:11:18
一.认识block    Block作为C语言的扩展,并不是高新技术,和其他语言的闭包或lambda表达式是一回事。需要注意的是由于Objective-C在iOS中不支持GC机制,使用Block必须自己管理内存,而内存管理正是使用Block坑最多的地方,错误的内存管理 要么导致return cycle内存泄漏要么内存被提前释放导致crash。 Block的使用很像函数指针,不过与函数最大的不同是: Block可以访问函数以外、词法作用域以内的外部变量的值。换句话说,Block不仅 实现函数的功能,还能携带函数的执行环境。 可以这样理解,Block其实包含两个部分内容 Block执行的代码,这是在编译的时候已经生成好的; 一个包含Block执行时需要的所有外部变量值的数据结构。 Block将使用到的、作用域附近到的变量的值建立一份快照拷贝到栈上。 Block与函数另一个不同是,Block类似ObjC的对象,可以使用自动释放池管理内存(但Block并不完全等同于ObjC对象)   先从一个简单的需求来说:传入两个数,并且计算这两个数的和,为此创建了这样一个block: 1 2 3 int (^sumOfNumbers)(int a, int b) = ^(int a, int b) { return a + b; };   这段代码等号左侧声明一个名为sumOfNumbers的代码块

iOS 面试全方位剖析 -- Block篇

余生长醉 提交于 2020-02-06 01:52:54
1.Block的本意 block本质上也是一个OC对象,它内部也有个isa指针, block是封装了函数调用以及函数调用环境的OC对象, block是封装函数及其上下文的OC对象 2.block截获变量 #import "SYDBlcok.h" // 全局变量----不截获全局变量 int global_var = 4; // 静态全局变量-----不截获全局静态变量 static int static_global_var = 5; @implementation SYDBlcok -(void)method { // 基本数据类型的局部变量----只截获值 int var = 6; // 对象类型的局部变量----连同所有修饰符一起截获 __unsafe_unretained id unsafe_ibject = nil; __strong id strong_obj = nil; // 局部静态变量---以指针形式截获局部静态变量 static int multiplier_static = 3; NSLog(@"multiplier_static:%d",multiplier_static); int(^Block)(int) = ^(int num) { NSLog(@"局部变量>基本数据类型:%d",var); NSLog(@"局部变量>对象类型%@----strong

IOS之block,一点小心得

寵の児 提交于 2020-02-06 01:48:21
作为一个iOS开发程序员,没用过block是不可能的。这次我探讨的是block原理,但是有些更深层次的东西,我也不是很清楚,以后随着更加了解block将会慢慢完善。   第一个问题,什么是block?   我们都会用block,但是block是什么呢,这是首先要弄清楚的概念。虽然,是什么并不影响我们用它,但是搞清楚原理我们才能更好的去使用它,我觉得作为一个程序员,需要时刻保持对事物原理追究的心态?   block的是本质是对象。但是你也可以说它是代码块、闭包、内联函数、函数指针...还有很多叫法,也可能这里的叫法都是错误的,或是不准确的,但是我个人觉得从功能上讲,可以这么理解。不过为了对oc的尊敬,还是叫它block吧,block就是block。在其他语言中也有类似block的语法,像javascript的闭包,函数里面的函数,java中的代码块,c中的函数指针等。就好像,事先放一段代码在这里,然后需要的时候回过头来调用。我们知道,代码执行是按顺序调用的,也就是我们常说的面向过程。但是block可以反向调用。只不过block可以写在函数里面,也可以说它是函数中的函数,它是比较特殊的函数。我们看下面的一个例子。 int main(int argc, const char * argv[]) { @autoreleasepool { int i = 0; void (^block)()

深入理解Block

丶灬走出姿态 提交于 2020-02-05 23:25:13
Block 简介 Mac OS X系统10.4及其iOS 4.0后引入了闭包的概念,这项语言特性是作为扩展而加入GCC编译器的。在Foundation框架中大量使用了Block。 块就是一个实现某个功能的函数闭包,这个函数闭包可以带有参数,也可以没有参数,可以有返回值也可以没有返回值者,用符号’^’来表示。块在声明的范围内,可以调用块外部的全局变量和局部变量。 void (^someBlock) () = ^{ //A simple block //Implementation: some code //无返回值,无参数 } void (^block) (int a, bool b) = ^(int a, bool b) { //some code //无返回值,带参数 } int (^block2) (int a, bool b) = ^(int a, bool b) { //some code //带参数带返回值 return integerValue; } 需要主意的是,block内部不能改变外部变量,想要在Block中改变变量的值,那么我们只需要在变量声明的时候加上__Block修饰符。 __block int a = 0; void (^block)() = ^{ a = 33; }; Block 的内部结构 每个Object-c变量都占据着某个内存区域

iOS Block详细介绍(block实现)

老子叫甜甜 提交于 2020-02-05 23:20:31
Block的实现 数据结构定义 block的数据结构定义如下图 对应的结构体定义如下: struct Block_descriptor { unsigned long int reserved; unsigned long int size; void (*copy)(void *dst, void *src); void (*dispose)(void *); }; struct Block_layout { void *isa; int flags; int reserved; void (*invoke)(void *, ...); struct Block_descriptor *descriptor; /* Imported variables. */ }; 通过改图 我们可以知道 一个block实例实际上由6部分组成。 1.isa指针。所有对象都有该指针,用于实现对象相关的功能。 2.flags 用于按bit位表示一些block的附加信息。本文后面介绍 block copy 的实现代码可以看到对该变量的使用。 3.reserved 保留变量 4.invoke 函数指针 指向具体的block实现的函数调用地址 5.descriptor 表示该block的附加描述信息 主要是size 大小 以及 copy 和 dispose函数的指针 6.variables capture