一个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];
        
        
    }];
}
原文地址:https://www.cnblogs.com/samyangldora/p/4608477.html