zoukankan      html  css  js  c++  java
  • iOS多个UIAlertView类问题处理---读书笔记

    开发 iOS 时经常用到 UIAlertView 类,该类提供了一种标准视图,可向用户展示警告信息。当用户按下按钮关闭该视图时,需要用委托协议(delegate protocol)来处理此动作,但 是,要想设置好这个委托机制,就得把创建警告视图和处理按钮动作的代码分开。由于代码 分作两块,所以读起来有点乱。比方说,我们在使用 UIAlertView 时,一般都会这么写: 

    - (void)askUserAQuestion {
        UIAlertView *alert = [[UIAlertView alloc]
                              initWithTitle:@"Question"
                              message:@"What do you want to do?"
                              delegate:self
                              cancelButtonTitle:@"Cancel"
                              otherButtonTitles:@"Continue", nil];
        [alert show];
    }
    

      

    // UIAlertViewDelegate protocol method
    - (void)alertView:(UIAlertView *)alertView
    clickedButtonAtIndex:(NSInteger)buttonIndex
    {
        if (buttonIndex == 0) {
            [self doCancel];
        }
        else {
            [self doContinue];
        }
    }
    

      

    如果想在同一个类里处理多个警告信息视图,那么代码就会变得更为复杂,我们必须在 delegate 方法中检查传入的 alertView 参数,并据此选用相应的逻辑。要是能在创建警告视图 的时候直接把处理每个按钮的逻辑都写好,那就简单多了。这可以通过关联对象来做。创建 完警告视图之后,设定一个与之关联的“块”(block) , 等到执行 delegate 方法时再将其读出 来。此方案的实现代码如下: 

    -(void)askUserAQuestion{
        UIAlertView *alert = [[UIAlertView alloc]
                              initWithTitle:@"第一个Question" message:@"What do you want to do?"
                              delegate:self cancelButtonTitle:@"Cancel"
                              otherButtonTitles:@"Continue", nil];
        
        void(^block)(NSInteger) = ^(NSInteger buttonIndex){
            if (buttonIndex == 0) {
                NSLog(@"00000");
            }else{
                NSLog(@"111111");
            }
        };
        
        objc_setAssociatedObject(alert,
                                 EOCMyAlertViewKey,
                                 block,
                                 OBJC_ASSOCIATION_COPY);
        [alert show];
    }
    
    -(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
        
        void(^block) (NSInteger) = objc_getAssociatedObject(alertView, EOCMyAlertViewKey);
        block(buttonIndex);
        
    }
    

      

    以这种方式改写之后,创建警告视图与处理操作结果的代码都放在一起了,这样比原 来更易读懂,因为我们无须在两部分代码之间来回游走,即可明白警告视图的用处。但是, 采用该方案时需注意:块可能要捕获(capture)某些变量,这也许会造成“保留环”(retain cycle)。

    正如大家所见,这种做法很有用,但是只应该在其他办法行不通时才去考虑用它。若是 滥用,则很快就会令代码失控,使其难于调试。“保留环”产生的原因很难查明,因为关联对 象之间的关系并没有正式的定义(formal definition),其内存管理语义是在关联的时候才定义 的,而不是在接口中预先定好的。使用这种写法时要小心,不能仅仅因为某处可以用该写法 就一定要用它。想创建这种 UIAlertView 还有个办法,那就是从中继承子类,把块保存为子类 中的属性。若是需要多次用到 alert 视图,那么这种做法比使用关联对象要好。 

  • 相关阅读:
    php极光网络一键登录(yii框架)
    Sublime Text3将多行转为为一行 | Sublime Text 快速分别独立选中多行
    mysql 将时间戳转换成日期格式
    Vant主题定制修改颜色样式
    TypeError: this.getOptions is not a function 引入less一直报错
    export defaul 和 export定义和区别
    Vue vant引入,tabbar封装使用示例
    php去除富文本编辑器中的内容格式
    ES6:高级数组函数,filter/map/reduce
    [BZOJ2793][Poi2012]Vouchers
  • 原文地址:https://www.cnblogs.com/kw-ios/p/3711663.html
Copyright © 2011-2022 走看看