块代码

2019-08-23  本文已影响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
上一篇 下一篇

猜你喜欢

热点阅读