• 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 视图,那么这种做法比使用关联对象要好。 

  • 相关阅读:
    Unix命令大全
    vs2008 与 IE8出现的兼容性问题
    Java 创建文件、文件夹以及临时文件
    如何修改Wamp中mysql默认空密码
    PAT 乙级真题 1003.数素数
    Tags support in htmlText flash as3
    DelphiXE4 FireMonkey 试玩记录,开发IOS应用 还是移植
    10 Great iphone App Review sites to Promote your Apps!
    HTML tags in textfield
    Delphi XE4 IOS 开发, "No eligible applications were found“
  • 原文地址:https://www.cnblogs.com/kw-ios/p/3711663.html
Copyright © 2020-2023  润新知