iOS:使用block代碼塊實現事件處理過程中的回調


block是什么,這里就不多加強調了,它的優點:

第一:執行效率高,速度快

第二:使用起來比代理簡單,省卻不少代碼,增強代碼美感

 

有一些小的知識點要強調一下:

第一點:它類似於一個匿名函數,也跟java中的匿名內部類相似,但是,記住,它是一種數據類型,因為它內部是一個結構體,有方法有屬性,所以它具有對象的特征;

第二點:在類中聲明block為屬性時,如果使用assgin修飾,那么它被放到了棧中,方法已過就會被銷毀,所以,盡量使用copy作為修飾詞,這樣一來block就被存放到了堆中,生命周期就會延長,保證block不會被立即銷毀;

第三點:要防止循環引用,造成線程死鎖,所以,有時需要加上__weak修飾。

第四點:為什么多用copy修飾,而不用strong修飾,這是MRC時期遺留下來的寫法習慣,其實用strong也可以修飾,但是盡量用copy。

 

block既可以作為屬性,單獨賦值然后回調;也可以作為一個方法的參數使用,再進行回調,舉例如下,直接代碼演示:

我的例子過程大概是:首先用戶瀏覽題庫時,點擊收藏按鈕,彈出收藏界面,用戶選擇完某一個文件夾后,隱藏收藏界面,提示收藏成功!

例子一:block使用屬性單獨賦值后回調

這是收藏界面類的回調代碼

#import <UIKit/UIKit.h>

//聲明block,用作選擇收藏文件后的回調處理
typedef void (^CollectionBlock)();     //選擇文件夾
typedef void (^CompleteHandleBlock)(); //選完之后的處理


@interface KJCollectionView : UITableView
@property (copy,nonatomic)CollectionBlock collectionBlock;
@property (copy,nonatomic)CompleteHandleBlock completeBlock;
-(instancetype)initWithFrame:(CGRect)frame withFiles:(NSArray *)files;

@end




#import "KJCollectionView.h"
#import "KJMyQueBankFile.h"

@interface KJCollectionView()<UITableViewDataSource,UITableViewDelegate>
@property (strong,nonatomic)NSArray *allFiles;
@end

@implementation KJCollectionView

-(instancetype)initWithFrame:(CGRect)frame withFiles:(NSArray *)files
{
    self = [super initWithFrame:frame];
    if (self) {
        self.dataSource = self;
        self.delegate = self;
        self.tableHeaderView = [UILabel createLabel:CGRectMake(0, 0, SCREEN_WIDTH, 50) title:@"請選擇收藏位置" titleColor:HMColor(13, 195, 176) alignmentType:NSTextAlignmentCenter size:16];
        self.tableFooterView = [[UIView alloc]initWithFrame:CGRectZero];
        self.allFiles = [NSArray arrayWithArray:files];
        MoveUnderLine(self);
    }
    return self;
}

#pragma mark - block回調,為block屬性賦值
-(void)setCollectionBlock:(CollectionBlock)collectionBlock{
    if (_collectionBlock != collectionBlock) {
       _collectionBlock = collectionBlock;
    }
}
-(void)setCompleteBlock:(CompleteHandleBlock)completeBlock{
    if (_completeBlock != completeBlock) {
        _completeBlock = completeBlock;
    }
}


#pragma mark - UITableViewDataSource
#pragma mark - Required

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
    return self.allFiles.count;
}

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    
    static NSString *reuseIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:reuseIdentifier];
    if (!cell) {
        cell = [[UITableViewCell alloc]init];
    }
    cell.accessoryView = [UIButton createButton:CGRectMake(0, 0, 30, 30) imageName:@"default_true" target:self Done:@selector(chooseFileDone:)];
    cell.imageView.image = [UIImage imageNamed:[self.allFiles[indexPath.row] file_image]];
    cell.textLabel.text = [self.allFiles[indexPath.row] file_Name];
    return cell;
}


#pragma mark - Optional
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
    return 50;
}

#pragma mark - UITableViewDelegate
#pragma mark - Optional
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
    cell.accessoryView = [UIButton createButton:CGRectMake(0, 0, 30, 30) imageName:@"selected_ture" target:nil Done:nil];

    //回調處理
    _collectionBlock();
    _completeBlock();
}

#pragma mark - 按鈕選擇文件夾
-(void)chooseFileDone:(UIButton *)btn{
    UITableViewCell *cell = (UITableViewCell *)btn.superview;
    cell.accessoryView = [UIButton createButton:CGRectMake(0, 0, 30, 30) imageName:@"selected_ture" target:nil Done:nil];
    
    //回調處理
    _collectionBlock();
    _completeBlock();
}
@end

這是在題庫類中給block傳遞回調處理的代碼:直接通過屬性賦值

#pragma mark - 點擊收藏按鈕時的代理方法
/**
 *  收藏作業
 *  @param indexPath     當前cell中選擇按鈕選中后的cell
 *  @param btn           收藏按鈕
 *  @param collectionTag 當前cell中收藏按鈕的tag
 */
-(void)finishedClickedCollectionFileIndexPath:(NSIndexPath *)indexPath CollectionBtn:(UIButton *)btn{
    
    //創建收藏文件夾視圖和蒙版視圖
    self.collectionView = [[KJCollectionView alloc]initWithFrame:CGRectMake(0, 0, 260, 200) withFiles:self.filesArrayM];
    self.collectionView.layer.cornerRadius = 3.0;
    self.collectionView.layer.masksToBounds = YES;
    self.collectionView.center = [UIApplication sharedApplication].keyWindow.center;
    self.coverView = [[UIView alloc]initWithFrame:self.view.bounds];
    self.coverView.backgroundColor = HMColorRGBA(51, 51, 51, 0.3);
    [self.view addSubview:self.collectionView];
    [self.view addSubview:self.coverView];
    [self.view insertSubview:self.collectionView aboveSubview:self.coverView];
    __weak typeof(self) weakSelf = self;
    
 
   //為選擇文件的block賦值
    self.collectionView.collectionBlock = ^(){
        //取出收藏字典
        KJChooseHomeworkDicM *checkBtnDicManager = [KJChooseHomeworkDicM sharedCheckBtnDicMManager];
        [checkBtnDicManager.collectionDicM setObject:indexPath forKey:indexPath];
        [btn setSelected:YES];
        //獲取作業模型
        KJLog(@"clickedCollection:%@",[weakSelf.homeworkCellFrames[indexPath.row] defaultFH]);
        
    };
    
   //為選完文件后的block賦值
    self.collectionView.completeBlock = ^(){
        [MBProgressHUD showSuccess:@"收藏成功"];
        //移除收藏文件夾視圖和蒙版視圖
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            [weakSelf.collectionView removeFromSuperview];
            [weakSelf.coverView removeFromSuperview];
            [weakSelf setCollectionView:nil];
            [weakSelf setCoverView:nil];
        });
    };
}

例子二:block作為方法的參數賦值后再進行回調

這是收藏界面類的回調代碼

#import <UIKit/UIKit.h>

//聲明block,用作選擇收藏文件后的回調處理
typedef void (^CollectionBlock)();     //選擇文件夾
typedef void (^CompleteHandleBlock)(); //選完之后的處理


@interface KJCollectionView : UITableView
@property (copy,nonatomic)CollectionBlock collectionBlock;
@property (copy,nonatomic)CompleteHandleBlock completeBlock;
-(instancetype)initWithFrame:(CGRect)frame withFiles:(NSArray *)files;

//聲明一個方法
-(void)chooseFile:(CollectionBlock )collectionBlock compeleteChooseBlock:(CompleteHandleBlock)completeBlock;
@end


//  Created by mac on 16/5/20.
//  Copyright © 2016年 mac. All rights reserved.
#import "KJCollectionView.h"
#import "KJMyQueBankFile.h"

@interface KJCollectionView()<UITableViewDataSource,UITableViewDelegate>
@property (strong,nonatomic)NSArray *allFiles;
@end

@implementation KJCollectionView

-(instancetype)initWithFrame:(CGRect)frame withFiles:(NSArray *)files
{
    self = [super initWithFrame:frame];
    if (self) {
        self.dataSource = self;
        self.delegate = self;
        self.tableHeaderView = [UILabel createLabel:CGRectMake(0, 0, SCREEN_WIDTH, 50) title:@"請選擇收藏位置" titleColor:HMColor(13, 195, 176) alignmentType:NSTextAlignmentCenter size:16];
        self.tableFooterView = [[UIView alloc]initWithFrame:CGRectZero];
        self.allFiles = [NSArray arrayWithArray:files];
        MoveUnderLine(self);
    }
    return self;
}

#pragma mark - block回調,通過方法為block屬性賦值
-(void)chooseFile:(CollectionBlock )collectionBlock compeleteChooseBlock:(CompleteHandleBlock)completeBlock{
    
    if (_collectionBlock != collectionBlock) {
        _collectionBlock = collectionBlock;
    }
    if (_completeBlock != completeBlock) {
        _completeBlock = completeBlock;
    }
}

#pragma mark - UITableViewDataSource
#pragma mark - Required

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
    return self.allFiles.count;
}

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    
    static NSString *reuseIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:reuseIdentifier];
    if (!cell) {
        cell = [[UITableViewCell alloc]init];
    }
    cell.accessoryView = [UIButton createButton:CGRectMake(0, 0, 30, 30) imageName:@"default_true" target:self Done:@selector(chooseFileDone:)];
    cell.imageView.image = [UIImage imageNamed:[self.allFiles[indexPath.row] file_image]];
    cell.textLabel.text = [self.allFiles[indexPath.row] file_Name];
    return cell;
}


#pragma mark - Optional
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
    return 50;
}

#pragma mark - UITableViewDelegate
#pragma mark - Optional
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
    cell.accessoryView = [UIButton createButton:CGRectMake(0, 0, 30, 30) imageName:@"selected_ture" target:nil Done:nil];

    //回調處理
    _collectionBlock();
    _completeBlock();
}

#pragma mark - 按鈕選擇文件夾
-(void)chooseFileDone:(UIButton *)btn{
    UITableViewCell *cell = (UITableViewCell *)btn.superview;
    cell.accessoryView = [UIButton createButton:CGRectMake(0, 0, 30, 30) imageName:@"selected_ture" target:nil Done:nil];
    
    //回調處理
    _collectionBlock();
    _completeBlock();
}
@end

這是在題庫類中給block傳遞回調處理的代碼:直接將要賦值的block寫入到方法中

#pragma mark - 點擊收藏按鈕時的代理方法
/**
 *  收藏作業
 *  @param indexPath     當前cell中選擇按鈕選中后的cell
 *  @param btn           收藏按鈕
 *  @param collectionTag 當前cell中收藏按鈕的tag
 */
-(void)finishedClickedCollectionFileIndexPath:(NSIndexPath *)indexPath CollectionBtn:(UIButton *)btn{
    
    //創建收藏文件夾視圖和蒙版視圖
    self.collectionView = [[KJCollectionView alloc]initWithFrame:CGRectMake(0, 0, 260, 200) withFiles:self.filesArrayM];
    self.collectionView.layer.cornerRadius = 3.0;
    self.collectionView.layer.masksToBounds = YES;
    self.collectionView.center = [UIApplication sharedApplication].keyWindow.center;
    self.coverView = [[UIView alloc]initWithFrame:self.view.bounds];
    self.coverView.backgroundColor = HMColorRGBA(51, 51, 51, 0.3);
    [self.view addSubview:self.collectionView];
    [self.view addSubview:self.coverView];
    [self.view insertSubview:self.collectionView aboveSubview:self.coverView];
    __weak typeof(self) weakSelf = self;

//把block放入方法中 [self.collectionView chooseFile:
^{ //取出收藏字典 KJChooseHomeworkDicM *checkBtnDicManager = [KJChooseHomeworkDicM sharedCheckBtnDicMManager]; [checkBtnDicManager.collectionDicM setObject:indexPath forKey:indexPath]; [btn setSelected:YES]; [MBProgressHUD showSuccess:@"收藏成功"]; //獲取作業模型 KJLog(@"clickedCollection:%@",[weakSelf.homeworkCellFrames[indexPath.row] defaultFH]); } compeleteChooseBlock:^{ //移除收藏文件夾視圖和蒙版視圖 dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ [MBProgressHUD hideHUD]; [weakSelf.collectionView removeFromSuperview]; [weakSelf.coverView removeFromSuperview]; [weakSelf setCollectionView:nil]; [weakSelf setCoverView:nil]; }); }]; }

 

上面兩種演示截圖達到的效果是一樣的:

點擊題庫中的收藏                     選擇文件夾收藏      

    

顯示收藏成功                      移除文件夾視圖

    

 

本人原創,轉載須注明出處,謝謝!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM