Block使用总结
block的使用总结:如果有感觉任何遗漏的话,欢迎留言补充,Block的循环使用那部分,这里我只贴出了解决方案,注意点应该是没有问题的
Block的使用
int a = 10;
NSLog(@"1-----------%d %p",a,&a);
void(^block)(void) = ^{
NSLog(@"2-----------%d %p",a,&a);
};
a = 20;
block();
NSLog(@"3-----------%d %p",a,&a);
输出结果:

结论:
从输出结果可以看出block内和block外是两个作用域,内部的指针a和外部的指针a虽然名字一样但他们的内存地址已经不同了,这也就是我们可以内部修改局部变量的原因。在block内部会将局部变量的指正复制一份,这样内部和外部就不是一个指针了,就算你重新给内部指针赋值,也无法改变外部指针的指向,他们只是名字相同。
__block int a = 10;
NSLog(@"1-----------%d %p",a,&a);
void(^block)(void) = ^{
NSLog(@"2-----------%d %p",a,&a);
};
a = 20;
block();
NSLog(@"3-----------%d %p",a,&a);
输入结果

结论:
没有通过__block修饰则是将值传进去,而通过__block修饰之后是将变量的内存地址传进去,这样就可以修改变量的值。
static int a = 10;
NSLog(@"1-----------%d %p",a,&a);
void(^block)(void) = ^{
NSLog(@"2-----------%d %p",a,&a);
a = 30;
};
a = 20;
block();
NSLog(@"3-----------%d %p",a,&a);
输入结果:

结论:静态变量的内存地址一致,所以可以修改变量的值
_a = 10;
NSLog(@"1-----------%d %p",_a,&_a);
void(^block)(void) = ^{
NSLog(@"2-----------%d %p",_a,&_a);
};
_a = 20;
block();
NSLog(@"3-----------%d %p",_a,&_a);
输出结果

结论:全局变量的内存地址一致,所以可以修改变量值
总结:1.如果block访问的外部变量是局部变量,那么就是值传递,外界改了,不会影响里面
2.如果block访问的外部变量是__block或者static修饰,或者全局变量,那么就是指针传递,block里面的值和外界属于同一变量,外界改变,里面也会改变
以上都是无返回值的Block,可以举例一个有返回值的block
// 先定一个block函数
int (^sumFunction)(int a, int b) = ^(int x, int y)
{
return (x + y);
};
NSLog(@"--------------:%d",sumFunction(2, 3));//5
如果这个block经常用到,在可以外部定义一个block
typedef int(^sumFunction)(int a, int b);
在内部使用
// 先定一个block函数
sumFunction sum = ^(int x, int y)
{
return (x + y);
};
NSLog(@"--------------:%d",sum(2, 3));//5
block在fun的使用
+(void)sumFunctionWithA:(int)a withB:(int)b withBlock:(void (^)(int sum))sumBlock{
int sum = a+b;
sumBlock(sum);
}
全局的block在fun的使用
定义:
typedef void(^SumBlock)(int sum);
+(void)sumFunctionWithA:(int)a withB:(int)b withBlock:(SumBlock)sumBlock{
int sum = a+b;
sumBlock(sum);
}
[ViewController sumFunctionWithA:2 withB:4 withBlock:^(int sum) {
NSLog(@"---------------------------:%d",sum);//6
}];
外部调用
[ViewController sumFunctionWithA:2 withB:4 withBlock:^void(int sum) {
NSLog(@"--------------------:%d",sum);//6
}];
Block作为一个属性进行传值,比方A跳转到B页面,B页面个A传值
在B页面设置Block的全局,在.h的属性方法里设置,这里只写了一个全局的,property一定要用copy,因为block的存在栈上,需要copy到堆上才能我们才能对block的内存进行管理

typedef void(^SumBlock)(int sum); @interface ViewController : UIViewController @property(nonatomic,copy)SumBlock sumBlock;
@end
在B页面需要传值的时间里面调用,一定要加if,不然可能会出现错误

在A页面跳转B页面的使用使用:这里的vc.sumBlock如果不写,B页面一定需要加if,不然报错

Block的注意事项
在block内部使用外部指针且会造成循环引用的的情况下,需要使用
__weak typeof(self)weakSelf = self;
如果在block内部调用了延迟函数如果还是用弱指针则会取不到指针,因为已经会销毁了,则需要使用强指针在引用一次
__strong typeof(self)strongSelf = weakSelf;
浙公网安备 33010602011771号