块代码

作者: 东了个尼 | 来源:发表于2019-08-23 17:36 被阅读0次
1.块的基础知识

块与函数类似,只不过是直接定义在另外一个函数里的,和定义它的那个函数共享同一个范围内的东西。块用^符号来表示,后面跟着一堆花括号,括号里面是是块的实现代码。
举例下面就是个简单的块代码

^{
  block implementation here
}

块其实就是一个值,而且自有其数据类型。与int float 或Object-c对象一样,也可以把块赋给变量,然后像使用其他变量那样使用它。块类型的语法
块的常见用法
1.块代码作为方法参数与函数指针类似。下面列出一个带返回值和返回类型的块

int (^AddBlock)(int a, int b) =^(int a, int b) {
return a + b;
}

块的强大之处在于:在声明它的范围里,所有变量都可以为其所捕获。这也就是说,那个范围里的所有变量,在块里依然可以使用。

int additional = 5;
int (^AddBlock)(int a, int b) =^(int a, int b) {
return a + b + additional;
}
int add =  AddBlock(2,5) = 12;

默认情况下 块所捕获的变量是不可以在块内修改的。如果想修改外部变量,那么变量定义的时候需要加上__block 去修饰变量

__block int additional = 5;
int (^AddBlock)(int a, int b) =^(int a, int b) {
  additional = additional +2;
return a + b + additional;
}

如果块所捕获的变量是对象类型,那么就会自动保留它,系统在释放块的时候,也会将其一并释放。
如果将块定义在Object-c类的实例变量,那么除了可以访问类的所有实例变量之外,还可以使用self变量。块总能捕获实例变量所以在声明时无需加__block。不过通过读取或写入操作捕获了实例变量,那么也会自动把self变量一并捕获了,因为实例变量是与self所指代的实例关联在一起的。例如,下面这个块声明在EOCClass类的方法中

@interface EOCClass
- (void)anInstanceMethod{
      void (^someBlock)()= ^{

_anInstanceVariable = @"some";
NSlog(@"%@", _anInstanceVariable);
}
}

如果某个EOCClass实例正在执行anInstanceMethod方法,那么self变量就指向此实例。由于块里没有明确使用self变量,所以很容易就会忘记self变量其实也为块所捕获了。直接访问实例变量和通过self来访问是等效的:
self->_anInstanceVAriable=@"some";之所以要捕获self变量原因在于此。我们经常通过属性访问实例变量,这种情况下,就要指明self了:
self.aProperty = @"Something";
然而一定要记住self也是个对象,因而在捕获它时也会将其保留。如果self所指代的那个对象同时也保留了块,这种情况通常会导致保留环。

2.block作为方法参数的常见用法
//声明
typedef void(^ClickBlock)(NSInteger index);
//block属性
@property (nonatomic, copy) ClickBlock imageClickBlock;
例子2:作方法参数
//声明
typedef void (^handleBlock)();
//block作参数
- (void)requestForRefuseOrAccept:(MessageBtnType)msgBtnType messageModel:(MessageModel *)msgModel handle:(handleBlock)handle{
  ...
2.3.3 在定义方法时,声明Block型的形参

- (void)yourMethod:(return_type (^)(var_type))blockName;

- (void)addClickedBlock:(void(^)(id obj))clickedAction;


- (void)addClickedBlock:(void(^)(id obj))clickedAction{
    self.clickedAction = clickedAction;
    // :先判断当前是否有交互事件,如果没有的话。。。所有gesture的交互事件都会被添加进gestureRecognizers中
    if (![self gestureRecognizers]) {
        self.userInteractionEnabled = YES;
        // :添加单击事件
        UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tap)];
        [self addGestureRecognizer:tap];
    }
}

- (void)tap{
    if (self.clickedAction) {
        self.clickedAction(self);
    }
}

#import <Foundation/Foundation.h>
typedef void (^SureActionBlock)(void);
typedef void (^CancleActionBlock)(void);
@interface FDDAlertViewController : NSObject
@property (nonatomic, copy) SureActionBlock sureActionBlock;
@property (nonatomic, copy) CancleActionBlock cancleActionBlock;
+ (instancetype)defaultAlertViewController;
- (void)showAlertViewWithTitle:(NSString *)title
                       message:(NSString *)message
               sureActionBlock:(SureActionBlock)sureBlock
             cancleActionBlock:(CancleActionBlock)cancleBlock;
@end

@implementation FDDAlertViewController
+ (instancetype)defaultAlertViewController
{   
    static id instance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        instance = [[self alloc] init];
    });
    return instance;
}
- (void)showAlertViewWithTitle:(NSString *)title
                       message:(NSString *)message
               sureActionBlock:(SureActionBlock)sureBlock
             cancleActionBlock:(CancleActionBlock)cancleBlock{
    self.sureActionBlock =sureBlock;
    self.cancleActionBlock =cancleBlock;
    NSString *OKStr = AppLocalString(@"OK");
    NSString *cancleStr = AppLocalString(@"cancle");
    UIAlertController *Alert = [UIAlertController alertControllerWithTitle:title message:message preferredStyle:UIAlertControllerStyleAlert];
    UIAlertAction *sureAction = [UIAlertAction actionWithTitle:OKStr style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        if (self.sureActionBlock) {
            self.sureActionBlock();
        }
    }];

    UIAlertAction *cancleAction = [UIAlertAction actionWithTitle:cancleStr style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
        if (self.cancleActionBlock) {
            self.cancleActionBlock();
        }
    }];
    [Alert addAction:cancleAction];
    [Alert addAction:sureAction];
    //获取当前展示的controller
    [[self currentViewController] presentViewController:Alert animated:YES completion:nil];
}
- (UIViewController *)currentViewController {
    UIWindow *window = [[UIApplication sharedApplication].delegate window];
    UIViewController *presentedVC = [[window rootViewController] presentedViewController];
    if (presentedVC) {
        return presentedVC;

    } else {
        return window.rootViewController;
    }
}
@end

相关文章

  • 普通代码块、构造代码块、静态代码块、同步代码块

    普通代码块:在方法或语句中出现的{}就称为普通代码块。普通代码块和一般的语句执行顺序由他们在代码中出现的次序决定-...

  • Java中静态代码块,构造代码块,构造函数代码块

    Java中静态代码块,构造代码块,构造函数代码块,普通代码块 静态代码块 : static代码块指的是static...

  • 09.代码块的概述

    代码块 局部代码块 局部代码块是定义在方法或语句中 构造代码块 构造代码块是定义在类中成员位置的代码块 静态代码块...

  • Java代码块详解

    Java中代码块指的是用 {} 包围的代码集合,分为4种:普通代码块,静态代码块,同步代码块,构造代码块 普通代码...

  • java中的代码块

    java中的代码块: 普通代码块,静态代码块,构造代码块 1. 普通代码块:在方法或者语句中, …… ...

  • Java基础之普通代码块、构造代码块、静态代码块、同步代码块

    1、概念 普通代码块:在方法或语句中出现的{}就称为普通代码块。普通代码块和一般的语句执行顺序由他们在代码中出现的...

  • 代码块

    rem

  • 代码块

    案例 邮箱:ithelei@sina.cn 技术讨论群:687856230 GoodLuck

  • 代码块

    代码块:1.普通代码块,在方法中写的代码块2.构造快,在类中定义的代码块,在创建对象时被调用,优于构造方法执行3....

  • 代码块

    定义:被“{}”包括的代码片段,使代码具备独立性,一般用于实现特定算法; 分类:普通代码块、静态代码块、同步代码块...

网友评论

      本文标题:块代码

      本文链接:https://www.haomeiwen.com/subject/pnjtectx.html