zoukankan      html  css  js  c++  java
  • 一个strong属性导致的一个bug

    问题描述

      - 今天写项目写一个下拉菜单,第一次下拉之后,再点一下可以移除,但是再点一下应该可以继续下拉出来但是就是不出来了。

    解决思路

      - 经过检查可以移除视图,但是downMenu一直有值,经过在经过断点调试发现并没有销毁。这时就应该想到为什么呢?此时回头看属性,发现是strong,因为在ARC中没有强引用的对象才会被销毁,虽然视图销毁了,但是我们控制器依然引用了它,所有没有销毁。

      - 此时我们有两种解决方法,一种就是用weak,一种就是在调用隐藏之后,给属性赋值为nil.

     1 #pragma mark - 是否下拉菜单
     2 - (void)downDrapView
     3 {
     4     if (self.popMenu == NO) {
     5         
     6         [self downMenu];
     7         
     8         
     9         NSLog(@"%@",self.downMenu);
    10     }else{
    11         
    12         [self.downMenu hide];
    13         
    14         self.downMenu = nil;
    15         
    16     }
    17     _popMenu = !_popMenu;
    18     
    19     
    20 }

    误区

      - 在我们正常思维下,移除视图之后,肯定会重新创建下,但是事实并没有。

           

    (图1)

                        

    (图2)

    (图3)

    @interface SAMHallViewController ()<SAMActiveMenuDelegate>
    
    
    
    /** 判断是下拉还是隐藏 */
    @property (nonatomic, assign) BOOL popMenu;
    
    /** downMenu */
    #warning 这里面要用weak要不然移除视图之后对象还是依然在,永远不会新建
    @property (nonatomic, strong) SAMDownMenu *downMenu;
    
    @end

    - (SAMDownMenu *)downMenu { if (_downMenu == nil) { SAMMenuItem *item = [SAMMenuItem menuItemWithTitle:nil withImage:[UIImage imageNamed:@"Development"]]; SAMMenuItem *item1 = [SAMMenuItem menuItemWithTitle:nil withImage:[UIImage imageNamed:@"Development"]]; SAMMenuItem *item2 = [SAMMenuItem menuItemWithTitle:nil withImage:[UIImage imageNamed:@"Development"]]; SAMMenuItem *item3 = [SAMMenuItem menuItemWithTitle:nil withImage:[UIImage imageNamed:@"Development"]]; SAMMenuItem *item4 = [SAMMenuItem menuItemWithTitle:nil withImage:[UIImage imageNamed:@"Development"]]; SAMMenuItem *item5 = [SAMMenuItem menuItemWithTitle:nil withImage:[UIImage imageNamed:@"Development"]]; NSArray *items = @[item,item1,item2,item3,item4,item5]; _downMenu = [SAMDownMenu showInView:self.view items:items oriY:0]; } return _downMenu; }
    #pragma mark - 是否下拉菜单
    - (void)downDrapView
    {
        if (self.popMenu == NO) {
            [self downMenu];
            
            NSLog(@"%@",self.downMenu);
        }else{
            [self.downMenu hide];
            
        }
        _popMenu = !_popMenu;
        
    + (instancetype)showInView:(UIView *)superView items:(NSArray *)items oriY:(CGFloat)oriY
    {
        NSUInteger count = items.count;
        
        //用来提醒开发者items里面元素个数传进来的应该是3的倍数
        if (count % 3) {
            [NSException exceptionWithName:@"items的总数不符合要求" reason:@"传入数组内的元素必须为3的倍数" userInfo:nil];
        }
        
        
        CGFloat x = 0;
        
        CGFloat row = count / kCols;
        CGFloat menuH = row * WH;
        
        SAMDownMenu *menu = [[self alloc] init];
        menu.frame = CGRectMake(x, oriY, SAMScreenBounds.size.width, menuH);
        
        //创建占位视图,要不然下拉会有段真空白
        UIView *blockView = [[UIView alloc] initWithFrame:menu.frame];
        blockView.backgroundColor = [UIColor blackColor];
        [superView insertSubview:blockView belowSubview:menu];
        //给模型赋值传到下面的,调用懒加载
        menu.items = items;
        
        [menu setUpAllBtns];
        [menu addAllLines];
        
        menu.transform = CGAffineTransformMakeTranslation(0, -menu.height);
        
        // 动画下拉菜单窗口
        [UIView animateWithDuration:0.5 delay:0 usingSpringWithDamping:0.5 initialSpringVelocity:0 options:UIViewAnimationOptionCurveLinear animations:^{
            menu.transform = CGAffineTransformIdentity;
        } completion:^(BOOL finished) {
            [blockView removeFromSuperview];
        }];
        
        
        menu.backgroundColor = [UIColor blackColor];
        
        [superView addSubview:menu];
        
      
        
        return menu;
    }
    #pragma mark - 添加所有中间间隔线
    - (void)addAllLines
    {
        for (int i = 0; i < kCols - 1; i++) {
            CGFloat x = (i + 1) * WH;
            
            UIView *lineView = [[UIView alloc] initWithFrame:CGRectMake(x, 0, 1, self.height)];
            
            lineView.backgroundColor = [UIColor whiteColor];
            
            [self addSubview:lineView];
        }
        
        UIView * lineView = [[UIView alloc] initWithFrame:CGRectMake(0, WH, self.width, 1)];
        lineView.backgroundColor = [UIColor whiteColor];
        
        [self addSubview:lineView];
    }
    #pragma mark - 记录所有item
    - (void)setUpAllBtns
    {
        for (NSUInteger i = 0; i < self.items.count; i++) {
            UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
            
            SAMMenuItem *item = self.items[i];
            
            [btn setTitle:item.title forState:UIControlStateNormal];
            [btn setImage:item.image forState:UIControlStateNormal];
            
            [self addSubview:btn];
          
            
            // 用一个数组存放每一个btn
            [self.btns addObject:btn];
           
        }
        
    }
    #pragma mark - 计算子控件button里面的位置
    - (void)layoutSubviews
    {
        [super layoutSubviews];
        
        CGFloat x = 0;
        CGFloat y = 0;
        
        CGFloat col = 0;
        //这个要用整数,要不然会成为电梯形的而局
       int row = 0;
        
        
        NSUInteger count = self.btns.count;
        
        for (NSUInteger i = 0; i < count; i++) {
            UIButton *btn = _btns[i];
            col = i % kCols;
            row = (int)i / kCols;
            x = col * WH;
            y = row * WH;
         
            btn.frame = CGRectMake(x, y, WH, WH);
        }
        
    }
    #pragma mark - 动画隐藏并移除视图
    - (void)hide
    {
        [UIView animateWithDuration:0.5 animations:^{
            
            self.transform = CGAffineTransformMakeTranslation(0, -self.height);
            
        } completion:^(BOOL finished) {
            
            [self removeFromSuperview];
            
            
        }];
    }
  • 相关阅读:
    python的logging模块
    python的random模块
    python3中time模块的用法及说明
    浅谈python模块的导入操作
    python3中,os.path模块下常用的用法总结
    OS模块的常用内置方法
    认识python中的set集合及其用法
    初识Python装饰器
    CentOS的软件包的管理之rpm和yum
    python中的函数对象与闭包函数
  • 原文地址:https://www.cnblogs.com/samyangldora/p/4608477.html
Copyright © 2011-2022 走看看