Block块

block的标志:^

特点:

1、可以保存代码

2、有返回值

3、有形参

4、调用方式和c语言一样

5、可以访问外部变量,但不能修改变量的值;如果使用__block关键字修饰的变量才可以。

1)创建

格式:

返回类型  ^block名称(参数类型表)=^(参数表){

代码;

};

block跟函数很像

a、不带参数

void (^myBlock)()=^{

NSLog(@“…000”);

};

b、带参数

int(^sumBlock)(int,int)=^(int a,int b){

return a+b;

}

c、用typedef定义block变量

typedef int(^)

定义block变量:

typedef int(^myblock)(int,int);

实现(重写):

myblock sblock = ^(int a,int b){

return a+b;

}

myblock subblock = ^(int a,int b){

return a-b;

}

使用:

NSLog(@“a+b = %d”,sblock(1,2));

NSLog(@“a+b = %d”,subblock(5,2));

如:

//定义一个带block参数的函数

-(void)xxxxxxx:(void(^)(NSString *strr))finishBlock{
    NSLog(@"xxxxxxxx");
    finishBlock(@"........");
    NSLog(@"jjjjjjjj");

}

//调用

- (IBAction)Blockaction:(UIButton *)sender {

[self xxxxxxx:^(NSString *strr) {
        NSLog(@"%@",strr);

}];

}

结果:

6、Block的循环引用

1)__weak:表示引用为弱引用。对应在定义property时用的"weak"。弱引用不会影响对象的释放,即只要对象没有任何强引用指向,即使有100个弱引用对象指向也没用,该对象依然会被释放。不过好在,对象在被释放的同时,指向它的弱引用会自动被置nil,这个技术叫zeroing weak pointer。这样有效得防止无效指针、野指针的产生。__weak一般用在delegate关系中防止循环引用或者用来修饰指向由Interface Builder编辑与生成的UI控件。

2)__strong:表示引用为强引用。对应在定义property时的"strong"。所有对象只有当没有任何一个强引用指向时,才会被释放。

注意:如果在声明引用时不加修饰符,那么引用将默认是强引用。当需要释放强引用指向的对象时,需要将强引用置nil。

一个特别要注意的问题

苹果的文档中明确地写道:

You should decorate variables correctly. When using qualifiers in an object variable declaration,

the correct format is:

ClassName * qualifier variableName;

按照这个说明,要定义一个weak型的NSString引用,它的写法应该是:

NSString * __weak str = @"hehe"; // 正确!

而不应该是:
__weak NSString *str = @"hehe";  // 错误!

对于非ARC下, 为了防止循环引用, 我们使用__block来修饰在Block

对于ARC下, 为了防止循环引用, 我们使用__weak来修饰在Block。原理就是:ARC中,Block中如果引用了__strong修饰符的自动变量,则相当于Block对该变量的引用计数+1

不过好在,编译器会及时地给我们一个警告,提醒我们可能会发生这类型的问题:

对这种情况,我们一般用如下方法解决:给要进入Block的指针加一个__block修饰符。

这个__block在MRC时代有两个作用:

  • 说明变量可改
  • 说明指针指向的对象不做这个隐式的retain操作

一个变量如果不加__block,是不能在Block里面修改的,不过这里有一个例外:static的变量和全局变量不需要加__block就可以在Block中修改。

在ARC引入后,没有了retain和release等操作,情况也发生了改变:在任何情况下,__block修饰符的作用只有上面的第一条:说明变量可改。即使加上了__block修饰符,一个被block捕获的强引用也依然是一个强引用。

#include <stdio.h>

int main()
{
    int b = 5;
    int *a = &b;
    void (^blockFunc)() = ^(){
        int *c = a;
    };

    blockFunc();

    return 1;
}
程序中,同为int型的指针,a是被Block捕获的变量,而c是在Block内定义的变量。a和c存在的位置完全不同,如果Block存在于堆上(在ARC下Block默认在堆上),那么a作为Block结构体的一个成员,也自然会存在于堆上,而c无论如何,永远位于Block内实际执行代码的函数栈内。这也导致了两个变量生命周期的完全不同:c在Block的函数运行完毕,即会被释放,而a呢,只有在Block被从堆上释放的时候才会释放。

同上理,如果我们直接让Block捕获我们的myController引用,那么这个引用会被复制后(引用类型也会被复制)作为Block的成员变量存在于其所在的堆空间中,也就是为Block增加了一个指向myController对象的强引用,这就是造成循环引用的本质原因。

//------------------------------------------------------------------------------------

时间: 2024-10-15 17:20:12

Block块的相关文章

iOS之block块

Block块. 1.声明Block int (^myBlock)(int n) = ^(int num) 类型 (^名称)(需要传的参数)= ^(参数) 2 __block 变量 在block块中修改block块外部变量的值,只有将外部的变量前面加_ _(两个短杠才能修改) 3 __weak 变量 在ARC机制下,如果block中应用控制器对象或者其实例变量,block会对其强引用,导致拷贝一份控制器对象从而造成内存泄露.为了避免这一问题,则需要: __weak typeof(self)weak

Linux内核系列之Block块层(一)

.Block块层入口函数为 genhd_device_init(),先对该函数开始分析: 函数实现源码: static int __init genhd_device_init(void) {     bdev_map = kobj_map_init(base_probe, &block_subsys_lock);     blk_dev_init();     subsystem_register(&block_subsys);     return 0; }   .kobj_map_i

ARC中block块作为属性的使用笔记

ARC中block块作为属性的使用笔记 block较难理解,根据在内存中的分布情况就分为3种类型,根据使用的情形又分为很多很多种.虽然用起来容易,但使用不当会造成内存泄露,虽然都是这么说,但你真的研究过为什么会泄露吗?为什么有些时候外部变量进入block的时候会导致引用计数+1呢? 本人做过MRC以及ARC的开发,但大势所趋,ARC将是以后开发的主要模式,即使有MRC也是ARC混编MRC的代码,所以,本文的block的一些使用上的心得都基于ARC的,已经不考虑MRC的了,请看官注意,MRC与AR

【学习ios之路:Objective-C】block块语法.NSDate和NSDateFormatter

一.Block块语法 块语法:可以在函数内部定义匿名函数 格式: ^返回值类型(参数列表){函数体}其中返回值类型可以省略 block简单练习: ①.求两个数的最大值 //int (^)(int,int)//block类型 int (^max)(int,int) = ^(int a,int b) {//block的实现体 return a > b ? a : b; }; int value = max(4,6);          printf("%d",value); ②.将一

Objective-c中的Block(块)详解

Block初探 在Objective-c中NSArray是很常用的容器之一,很多时候我们需要对数组中的数据进行排序,因此与下面类似的代码会经常碰到: NSArray *sortedArray = [array sortedArrayUsingComparator: ^(id obj1, id obj2) { if ([obj1 integerValue] > [obj2 integerValue]) { return (NSComparisonResult)NSOrderedDescending

「ios」block块中使用self

[问题现象] 在block块中使用self时报警告:self strongly in this block is likely to lead to a retain cycle [问题解决] __block ViewController *blockSelf = self;_block = ^{ [blockSelf->_items addObject:@"Hello!"];};

关于block块使用的6点注意事项

对于刚学习OC新伙伴,block块一直都是一个比较纠结.比较难懂的知识点,不过,在使用一段时间后,就会感觉很酸爽.block块的原理及使用我就不再赘述,网上有很多这方面的资料.我个人使用这么长时间以来,觉得使用block块应该注意以下几点. 一.在使用block前需要对block指针做判空处理 例如:XXXX为定义的block块 if (XXXX ) {                  if(XXXX != nil){ XXXX(参数);            或 XXXX(参数);  }  

黑马程序员-2.block块

吐槽:刚开始接触iOS的时候真的挺不适应的,里面出现了很多新玩意,不过还好我比较喜欢新鲜事物,以后整理些iOS中比较新颖的东西. block就是一个,不过有了block之后省去了上下翻代码的麻烦,很好用,推荐!! 1.Block定义 Block是OC中的一种数据类型,在iOS开发中被广泛使用 ^是Block的特有标记,Block的实现代码包含在{}之间 大多情况下,以内联inline函数的方式被定义和使用 Block与C语言的函数指针有些相似,但使用起来更加灵活 示例 void(^demoBlo

oracle BBED 直接改动数据库block块

1.BBED配置 1)将相应文件放到$ORACLE_HOME/rdbms/mesg和$ORACLE_HOME/rdbms/lib中: --将lib中bbedus.msb和bbedus.msg 放在$ORACLE_HOME/rdbms/mesg下 --将lib中sbbdpt.o和ssbbded.o 放在$ORACLE_HOME/rdbms/lib下 2)安装BBED --在$ORACLE_HOME/rdbms/lib下运行: [[email protected] lib]$ make -f ins

Block --- 块语法

block 块语法.  --- 匿名函数 block可以在函数内部定义匿名函数. blocK -- 实现两个数的最大值. 函数: #import <Foundation/Foundation.h> #import "Person.h" //1.输出I love ios void output() { printf("I love ios\n"); } //2.求两个数的最大 int maxValue(int x, int y) { return x &g