• iOS block和代理的区别


      block和代理是iOS开发中实现回调的两种方式,大多数情况下是用哪个都可以,主要看个人喜好。本文主要是对两者做一下对比。

    1.block简介

      在 iOS中, block一共分三种。
      (1)全局静态 block,不会访问任何外部变量,执行完就销毁。

     ^{
            NSLog(@"Hello World!");
        }();
    

    (2)保存在栈中的 block,当函数返回时会被销毁,和第一种的区别就是调用了外部变量。

     
        [UIView animateWithDuration:3 animations:^{
           
            self.view.backgroundColor = [UIColor redColor];
        }];
    

      (3)保存在堆中的 block,当引用计数为 0 时会被销毁。例如按钮的点击事件,一直存在,即使执行过,也不销毁,因为按钮还可能被点击,持有按钮的View被销毁,它才会被销毁。

    #import <UIKit/UIKit.h>
    
    typedef void(^ButtonClickBlcok)();
    
    @interface TestView : UIView
    
    @property (nonatomic, copy) ButtonClickBlcok buttonClickBlcok;
    
    @end
    
    
    #import "TestView.h"
    
    @implementation TestView
    
    - (IBAction)buttonClick:(id)sender {
        
        if (self.buttonClickBlcok) {
            self.buttonClickBlcok();
        }
    }
    @end
    

    2.block优点

      block的代码可读性更好。因为应用block和实现block的地方在一起。代理的声明和实现就分开来了,在两个类中。代理使用起来也更麻烦,因为要声明协议、声明代理、遵守协议、实现协议里的方法。block不需要声明,也不需要遵守,只需要声明和实现就可以了。
      block是一种轻量级的回调,可以直接访问上下文,由于block的代码是内联的,运行效率更高。block就是一个对象,实现了匿名函数的功能。所以我们可以把block当做一个成员变量、属性、参数使用,使用起来非常灵活。像用AFNetworking请求数据和GCD实现多线程,都使用了block回调。

    3.block缺点

      blcok的运行成本高。block出栈需要将使用的数据从栈内存拷贝到堆内存,当然对象的话就是引用计数加1,使用完或者block置nil后才销毁。delegate只是保存了一个对象指针(一定要用week修饰delegate,不然也会循环引用),直接回调,没有额外消耗。就像C的函数指针,只多做了一个查表动作。
      block容易造成循环引用,而且不易察觉。因为为了blcok不被系统回收,所以我们都用copy关键字修饰,实行强引用。block对捕获的变量也都是强引用,所以就会造成循环引用。

    #import "ViewController.h"
    
    typedef void(^TestBlock)(void);
    
    @interface ViewController ()
    {
        void (^_testCycleBlock)(void);
    }
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
      
        [super viewDidLoad];
        
        __weak ViewController *weakSelf = self;
        _testCycleBlock = ^{
    
            /**
              //引发循环引用
              NSLog(@"%@", self);
             */
            //防止循环引用
            NSLog(@"%@", weakSelf);
        };
    }
    @end
    

    4.如何使用

      优先使用block。
      如果回调函数很多,多余三个使用代理。
      如果回调的很频繁,次数很多,像UITableview,每次初始化、滑动、点击都会回调,使用代理。
      block和代理都各有优缺点,所以我们一定要理解区分使用场景,应用适合的回调方式。优化APP的性能,提高流畅性,从点滴做起。

  • 相关阅读:
    python 运用numpy库与matplotlib库绘制数据图
    pil库的介绍与应用
    使用jieba库与wordcloud库第三方库进行词频统计
    将驼峰命名转为连字符格式
    数组去重的多种方法
    数字美化-pretty-number 将数字转换成k 、w
    npm方式开发的插件使用yarn link的方式引入到目标项目中,在目标项目中无法读取到Vue,vuex, vue-i18n的解决方法
    eslint配置
    webpack 中的 process.env
    类型“VueConstructor<Vue>”上不存在属性“install”。ts(2339)
  • 原文地址:https://www.cnblogs.com/doujiangyoutiao/p/7514846.html
Copyright © 2020-2023  润新知