• A包含B,用block实现A和B互相调用更新数据


    A包含B,如何实现A和B互相调用更新数据。
    添加通知了不是立即生效的,需要系统调度。而block是立即生效的。
    不要用通知来回发送通知,通知有很多弊端,特别是多线程环境下,当一个控件刚添加了通知还没有正式生效,另一个线程发送了对应通知,就有概率闪退 。
    所以尽量少用或不用通知,尽量用block来代替。
    理论上因为A包含B,A可以知道B的数据,但是无法知道B的私有数据,当然若A只是创建B,但是没有持有B的指针也无法知道B的数据。通过两者来回发送通知当然能实现,只是通知是一对多,有概率闪退的问题,尽量别用。那么可以在创建B时给它传递一个bock,对A特别关注的数据B更新该数据时同步给A。
    现在是一个A页面通过蘑菇街架构创建了一个B页面并把一个block给B页面,A页面没有持有B页面的指针,当B页面更新了数据后,通过block的回掉更新了A页面的数据和刷新了列表。
    A页面创建B页面:

            NSMutableDictionary *userInfo = [NSMutableDictionary dictionary];
            void(^selectEntityBlock)(FHFollowListUnitEntity *followListUnitEntity, BOOL isFollow) = ^(FHFollowListUnitEntity *followListUnitEntity, BOOL isFollow) {
                @strongify(self);
                [self freshTabWithFollowListUnitEntity:followListUnitEntity isFollow:isFollow];
            };
            [userInfo setSafeObject:entity forKey:@"followListUnitEntity"];
            [userInfo setSafeObject:selectEntityBlock forKey:@"block"];
            [userInfo setSafeObject:@(entity.dynamic_id) forKey:@"dynamic_id"];
            [BITRouter openURL:@"gb://FHImageTextDetailViewController" withUserInfo:userInfo completion:nil];
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    A页面通过B页面的回调数据更新数据并刷新表格处理:

    -(void)freshTabWithFollowListUnitEntity:(FHFollowListUnitEntity *)followListUnitEntity isFollow:(BOOL)isFollow
    {
        if(!followListUnitEntity || ![followListUnitEntity isKindOfClass:[FHFollowListUnitEntity class]] || isCommonUnitEmptyArray(self.models))
        {
            return;
        }
        if(!isFollow)
        {
            for(NSInteger i = 0; i < self.models.count; i++)
            {
                FHFollowListUnitEntity *entity = self.models[i];
                if(entity && [entity isKindOfClass:[FHFollowListUnitEntity class]] && followListUnitEntity.dynamic_id > 0 && (entity.dynamic_id == followListUnitEntity.dynamic_id))
                {
                    entity.is_collect = followListUnitEntity.is_collect;
                    entity.collect = followListUnitEntity.collect;
                    entity.is_praise = followListUnitEntity.is_praise;
                    entity.praise = followListUnitEntity.praise;
                    entity.is_evaluate = followListUnitEntity.is_evaluate;
                    entity.evaluate = followListUnitEntity.evaluate;
    //                [self.collectionView reloadData];
                    if(self.selectEntityBlock)
                    {
                        self.selectEntityBlock(followListUnitEntity, NO);
                    }
                    BOOL animationsEnabled = [UIView areAnimationsEnabled];
                    [UIView setAnimationsEnabled:NO];
                    NSIndexPath *indexPath=[NSIndexPath indexPathForRow:i inSection:0];
                    [self.collectionView reloadItemsAtIndexPaths:[NSArray arrayWithObjects:indexPath,nil]];
                    [UIView setAnimationsEnabled:animationsEnabled];
                    return;
                }
            }
            
        }
        else
        {
            if(isCommonUnitEmptyString(followListUnitEntity.user_id))
            {
                return;
            }
            BOOL flag = NO;
            NSMutableArray *indexPaths = [NSMutableArray array];
            for(NSInteger i = 0; i < self.models.count; i++)
            {
                FHFollowListUnitEntity *entity = self.models[i];
                if(entity && [entity isKindOfClass:[FHFollowListUnitEntity class]] && followListUnitEntity.dynamic_id > 0 && ([entity.user_id isEqualToString:followListUnitEntity.user_id]))
                {
                    flag = YES;
                    entity.is_follow = followListUnitEntity.is_follow;
                    entity.follow_sum = followListUnitEntity.follow_sum;
                    [indexPaths addSafeObject:[NSIndexPath indexPathForRow:i inSection:0]];
    //                NSIndexSet *indexSet=[[NSIndexSet alloc]initWithIndex:i];
    //                //为了避免重新加载时出现不需要的动画(又名“闪烁”)
    //                BOOL animationsEnabled = [UIView areAnimationsEnabled];
    //                [UIView setAnimationsEnabled:NO];
    //                [self.collectionView reloadSections:indexSet];
    //                [UIView setAnimationsEnabled:animationsEnabled];
    //                return;
                }
            }
            if(flag)
            {
                BOOL animationsEnabled = [UIView areAnimationsEnabled];
                [UIView setAnimationsEnabled:NO];
                [self.collectionView reloadItemsAtIndexPaths:indexPaths];
                [UIView setAnimationsEnabled:animationsEnabled];
    //            [self.collectionView reloadData];
                if(self.selectEntityBlock)
                {
                    self.selectEntityBlock(followListUnitEntity, YES);
                }
            }
            
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75

    B页面通过block回调A页面注册的block传递数据:
    B页的子控件更新了数据,回调给B页面,然后回调A页面的block:

        self.writeEvaluateMessageCollectPraiseView.selectBlock = ^{
            @strongify(self);
            CHECK_JUMP_LOGIN;
            NSMutableDictionary *userInfo = [NSMutableDictionary dictionary];
            void(^freshBlock)(NSInteger dynamic_id, BOOL is_evaluate, NSInteger evaluate) = ^(NSInteger dynamic_id, BOOL is_evaluate, NSInteger evaluate){
                @strongify(self);
                if(dynamic_id > 0 && self.followListUnitEntity && (self.followListUnitEntity.dynamic_id == dynamic_id))
                {
                    self.model.detailEntity.is_evaluate = is_evaluate;
                    self.model.detailEntity.evaluate = evaluate;
                    self.writeEvaluateMessageCollectPraiseView.model = self.model;
                    
                    self.followListUnitEntity.is_evaluate = self.model.detailEntity.is_evaluate;
                    self.followListUnitEntity.evaluate = self.model.detailEntity.evaluate;
                    self.selectEntityBlock(self.followListUnitEntity, NO);
                }
    //            [self loadListDataWithIsFresh:YES];
            };
            [userInfo setSafeObject:freshBlock forKey:@"block"];
            [userInfo setSafeObject:@(self.model.dynamic_id) forKey:@"dynamic_id"];
            [BITRouter openURL:@"gb://FHEvaluateListViewController" withUserInfo:userInfo completion:nil];
        };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    B页通过请求数据更新了数据,回调A页面的block:

    -(void)loadListDataWithIsFresh:(BOOL)isFresh
    {
        @weakify(self);
        self.isFresh = isFresh;
        [NetWorkManager postWithPath:@"Dynamic/getDynamic" param:@{@"typeid":@(1),@"dynamic_id":@(self.model.dynamic_id)} dataClass:[FHDetailEntity class] isArray:NO].complete = ^(DYNetModel * _Nullable net, FHDetailEntity *data) {
            @strongify(self);
            if (net.errcode == DYNetModelStateSuccess) {
                self.isFresh = NO;
                if(data && [data isKindOfClass:[FHDetailEntity class]])
                {
                    if(isFresh)
                    {
                        if(self.selectEntityBlock && self.selectEntityBlock && [self.followListUnitEntity isKindOfClass:[FHFollowListUnitEntity class]])
                        {
                            self.model.detailEntity.is_follow = data.is_follow;
                            self.model.detailEntity.is_collect = data.is_collect;
                            self.model.detailEntity.collect = data.collect;
                            self.model.detailEntity.is_praise = data.is_praise;
                            self.model.detailEntity.praise = data.praise;
                            self.model.detailEntity.is_evaluate = data.is_evaluate;
                            self.model.detailEntity.evaluate = data.evaluate;
                            [self freshBlock];
                            self.writeEvaluateMessageCollectPraiseView.model = self.model;
                        }
                        return;
                    }
                    self.model.detailEntity = data;
                    [self.collectionView reloadData];
                    self.selectBtn.isSelectContent = self.model.detailEntity.is_collect;
                    self.writeEvaluateMessageCollectPraiseView.model = self.model;
                }
                else
                {
                    [self displayNoData];
                }
            }
            else
            {
                [self loadFail];
            }
        };
        
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44

    理论上因为是B是被包含的关系,无法直接访问A的数据,而A的数据可能被C直接更新的,也可能是A自己更新的数据,情况比较复杂,若A的数据变更时,忘记传递给B,就会造成B拿到的不是A的最新数据。若B只在部分处理时需要使用A的数据。正确的做法是A创建B注册一个B的block,B需要时,调用block通知A更新最新的B关注数据给B或单例。然后再使用数据。block是实时传递,不像通知在发出通知到收到通知需要时间差。
    A页面创建B页面注册一个B页面的block:

    - (UIViewController<ZJScrollPageViewChildVcDelegate> *)childViewController:(UIViewController<ZJScrollPageViewChildVcDelegate> *)reuseViewController forIndex:(NSInteger)index {
        @weakify(self);
        if(self.currentCell && self.player){
            self.currentCell.isPause = YES;
            [self.player clearPlayer];
            //返回关注的列表,暂停之前的播放
            [self.player stopPlay];
        }
        self.currentIndex = index;
        UIViewController<ZJScrollPageViewChildVcDelegate> *childVc = reuseViewController;
        if (!childVc) {
            if (index == 0) {
                self.attentionBtn.isSelected = YES;
                self.recommentBtn.isSelected = NO;
                QRHomeController *vc = [[QRHomeController alloc] init];
                self.attentionPage = vc;
                vc.type = @"2";
    //            vc.isFirstLoad = YES;
                vc.isFreshTable = YES;
            //    self.isLoadCurrencyStartup = NO;
                
                [self synchroData];
                self.attentionPage.synchroDataBlock = ^{
                    @strongify(self);
                    [self synchroData];
                };
                self.attentionPage.switchSelectPageBlock = ^(NSInteger selectPageIndex) {
                    @strongify(self);
                    [self synchroData];
                    [self.scrollPageView setSelectedIndex:1 animated:YES];
                };
                self.attentionPage.storeDataBlock = ^{
                    @strongify(self);
                    [self storeWithPage:self.attentionPage sno:0];
                };
                self.attentionPage.freshPageBlock = ^(NSInteger freshPageIndex) {
                    @strongify(self);
                    if(0 == freshPageIndex)
                    {
                        [self.attentionPage headerRefresh];
                    }
                    else
                    {
                        [self.recommentPage headerRefresh];
                    }
                };
                [self.attentionPage headerRefresh];
                childVc = vc;
            }
            else
            {
                self.attentionBtn.isSelected = NO;
                self.recommentBtn.isSelected = YES;
                QRHomeController *vc = [[QRHomeController alloc] init];
                self.recommentPage = vc;
                self.recommentPage.synchroDataBlock = ^{
                    @strongify(self);
                    [self synchroData];
                };
                self.recommentPage.switchSelectPageBlock = ^(NSInteger selectPage) {
                    @strongify(self);
                    [self synchroData];
                    [self.scrollPageView setSelectedIndex:0 animated:YES];
                };
                self.recommentPage.storeDataBlock = ^{
                    @strongify(self);
                    [self storeWithPage:self.recommentPage sno:1];
                };
                self.recommentPage.freshPageBlock = ^(NSInteger freshPageIndex) {
                    @strongify(self);
                    if(0 == freshPageIndex)
                    {
                        [self.attentionPage headerRefresh];
                    }
                    else
                    {
                        [self.recommentPage headerRefresh];
                    }
                };
                vc.type = @"1";
                vc.isFreshTable = YES;
                vc.isNotFirstPlay = NO;
                childVc = vc;
                [self synchroData];
            }
        }
        else
        {
        }
        return childVc;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92

    A页面同步数据给B页面的处理函数:

    -(void)synchroData
    {
        [self updateHomeControllerWithPage:self.attentionPage sno:0];
        [self updateHomeControllerWithPage:self.recommentPage sno:1];
    }
    
    -(void)updateHomeControllerWithPage:(QRHomeController *)page sno:(NSInteger)sno
    {
        if(page && [page isKindOfClass:[QRHomeController class]])
        {
            page.district_id = self.district_id;
            page.longStr = self.longStr;
            page.latiStr = self.latiStr;
            page.isNotFirstPlay = self.isNotFirstPlay;
            
            page.player = self.player;
            page.currentIndex = self.currentIndex;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    B页面需要时,调用block通知A页面更新最新的B关注数据给B或单例。然后再使用数据:

    - (void)configurationCell:(QRHomeVideoCell *)cell indexPath:(NSIndexPath *)indexPath {
        @weakify(self);
        NSMutableArray *arr1 = self.models;
        if (arr1.count>indexPath.row) {
            cell.latiStr = self.latiStr;
            cell.logStr = self.longStr;
            LCStoreModel *model = [arr1 objectAtSafeIndex:indexPath.row];
            [cell setModel:model];
            [cell setZanBlock:^(NSInteger ifZan) {
                @strongify(self);
                model.user_love = (ifZan == 0) ? NO : YES;
            }];
            [cell setChangeNoBlock:^(NSInteger count) {
                @strongify(self);
                [self.currentCell.commentBtn.titleL setText:[NSString stringWithFormat:@"%ld", count]];
            }];
            [cell setHitAttentionBlock:^(LCStoreModel * _Nonnull model) {
                @strongify(self);
                if(model && [model isKindOfClass:[LCStoreModel class]] && !isCommonUnitEmptyArray(self.models) && model.suppliers_id > 0)
                {
                    BOOL flag = NO;
                    NSMutableArray *arr =[NSMutableArray array];
                    for(NSInteger n = 0; n < self.models.count; n++)
                    {
                        LCStoreModel *entity = self.models[n];
                        if(entity && [entity isKindOfClass:[LCStoreModel class]] && (entity.suppliers_id > 0) && (model.suppliers_id == entity.suppliers_id) && (entity.goods_id != model.goods_id))
                        {
                            entity.user_focus = model.user_focus;
                            NSIndexPath *indexPath1 =[NSIndexPath indexPathForRow:n inSection:0];
                            [arr addObject:indexPath1];
                            flag = YES;
                        }
                    }
                    if(!isCommonUnitEmptyArray(arr))
                    {
                        //为了避免重新加载时出现不需要的动画(又名“闪烁”)
                        BOOL animationsEnabled = [UIView areAnimationsEnabled];
                        [UIView setAnimationsEnabled:NO];
                        [self.tableView reloadRowsAtIndexPaths:arr withRowAnimation:UITableViewRowAnimationNone];
                        [UIView setAnimationsEnabled:animationsEnabled];
                    }
                }
                if(self.type.intValue == 2){
                    if(self.synchroDataBlock)
                    {
                        self.synchroDataBlock();
                    }
                    self.isFreshTable = YES;
                    if(self.currentCell && self.player){
                        self.currentCell.isPause = YES;
                        [self.player clearPlayer];
                        //返回关注的列表,暂停之前的播放
                        [self.player stopPlay];
                    }
                    [self headerRefresh];
                    if(self.freshPageBlock)
                    {
                        self.freshPageBlock(1);
                    }
                }
                else
                {
                    //刷新推荐列表
                    if(self.freshPageBlock)
                    {
                        self.freshPageBlock(0);
                    }
                }
                [self loginIMaccount];
            }];
            cell.changePlayBlock = ^(BOOL isPause) {
                @strongify(self);
                if(isPause)
                {
                    [self.player pause];
                }
                else
                {
                    [self repeatPlayWithIsPause:YES];
                }
            };
            cell.endEditingBlock = ^{
                @strongify(self);
                [self.view endEditing:YES];
            };
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
  • 相关阅读:
    VUE识别访问设备是移动端还是pc端
    基于Springboot实现网上商城管理系统演示【项目源码+论文说明】
    尚硅谷(SpringCloudAlibaba微服务分布式)学习代码Eureka部分
    安洵杯2022 Web Writeup
    strace应用
    重装系统后没声音如何解决
    安洵杯 2022 复现
    java spring IOC的三种方式之XML形式
    SuperMap iServer 产品包类型说明
    交叉编译 Qt5.12 armv8(aarch64) 带 WebEngine - NVIDIA JETSON TX2
  • 原文地址:https://blog.csdn.net/jia12216/article/details/128110530