浅析ios开发中Block块语法的妙用


      事实上,任何一个应用的开发都离开多线程。而“块”block与GCD就是苹果OC语言中多线程的核心。
    
一.块的内部结构
     在oc中,块语法以闭包的形式存在,每一个Objective-C对象都占据着某个内存区域。块本身也是一个对象,在存放块的对象内存区域中,首个变量是指向Class的指针,该指针叫做isa。其余内存里含有块对象正常运转所需的各种信息。
    以下是块语法的内部结构变量。
    1.void*                                   isa(指向class的对象指针)
    2.int                                       flags
    3.int                                       reserved
    4.void(*)(void*,……)  invoke(函数指针)
    5.struct*                                 descriptor(结构体描述)
  
    根据上述块语法的内存结构可知,其中最重要的就是invoke变量,这是一个函数指针,指向的就是块的实现代码。

二.块在系统api回调中的应用
    在iOS的原生api中,有不少的地方都用到了块语法。其中最常见的主要是两个地方,一个就是数组和字典的块枚举,这种枚举方式是每一个NSArry和NSDictionary都自带的,其效率和便利性远远高于传统的for循环。
  

[self.p_tableArr enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {

                    <#code#>

                }]


另一个常见的地方就是页面跳转present之后的完成回调,

[self presentViewController:<(UIViewController *)> animated:<(BOOL)> completion:<^(void)completion>]


三.块语法在UIAlertView中的集中代码

  UIAlertView是一个弹窗控件,有一些按钮,最常见的就是确认和取消,UIAlertView有一个代理处理这些按钮,当用户点击后,该代理可以捕获按钮的下标,然后用户根据下标Index写一些逻辑代码。

  

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex


  快语法的第一个妙用就是可以直接在创建这个UIAlertView控件的时候就已经写好逻辑代码,完全不用写在以上回调中。

  以下是具体实现。

  第一步,申明一个全部的Block对象,根据UIAlertView的回调代理可知,该代理主要参数是一个NSInteger类型的参数,那么我们申明的Block对象可以根据代理的实际情况来创建。

@property(nonatomic,copy)void(^p_alertBlock)(NSInteger);


  第二部,在创建这个UIAltView的地方实现这个全部的Block对象。

  if(!self.p_alertBlock)

        {

            self.p_alertBlock = ^(NSInteger buttonIndex)

            {


                AccountViewController *acc = accc;

                switch (buttonIndex) {

                    case 0:

                        break;

                        

                    case 1:

                        

                        if([acc.p_fmdb deleteObjc:list])

                        {

                            [acc.p_tableArr removeObjectAtIndex:acc.p_didSelect];

                            [acc.p_table reloadData];

                        }

                        break;

                }

            };

        }

        UIAlertView *alt = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"tip",nil) message:NSLocalizedString(@"sureDelet", nil) delegate:self cancelButtonTitle:NSLocalizedString(@"cancel", nil) otherButtonTitles:NSLocalizedString(@"ok",nil), nil];

        [alt show];

   这是一个删除数据库操作的弹窗,当用户点击确认的时候删除数据库的对象,点击取消不做任何处理。
   第三步,在UIAlertView的代理中运行快。

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex

{

    self.p_alertBlock(buttonIndex);

}


  这个用法有一个好处就是可以在UIAlertView还未创建之前就已经确定了它按钮的处理,集中代码,看起来更加的方便和直观。

  以上只是一个事例,在系统很多控件中都可以这样实现,诸如UIActionSheet等。

  


  三.块语法替代Delegate

  提起ios的消息通知,就少不了代理Delegate。代理尽管很方便,可是实现的过程比较繁琐。如果使用块语法的话,我们可以提前把回调函数的代码实现封装到Block中作为参数传递给数据层,这样子实际上在代理回调中

if(self.delegate && [self.delegate respondsToSelector:@selector(setAddressSuccess:)])

        {

            [self.delegate setAddressSuccess:self.accountList.remark];

        }

这句话就被

Block(self.accountList.remark);所取代。

  是不是更加的便捷了呢?关键是你根本就不用声明代理,实现,设置代理,维护协议等等复杂的过程。

  

  代理还有一个限制就是必须要对象化,假如一个工具类是一个类的实例方法,你想在某些操作之后把数据回调给C层,这个时候代理就无法实行了,但是Block只不是是一个对象而已,就像NSString一样,可以帮助你实现。


  以上只是块语法在系统控件API回调中的妙用和两个类之间代理的妙用,更多的功能还有待在实际开发中逐步挖掘发现。

  

  仁者见仁,智者见智,块语法究竟强大到何种地步,等你用多了就知道了。


郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。