• OC语言-06-OC语言-block与protocol


    一、block

    1> 基本使用

    • 相当于用来存放代码的代码块
    • 效率高
    • 若没有形参可以省略小括号

    2> block与函数的相同点

    • 可以保存代码
    • 可以有返回值
    • 可以有形参
    • 调用方式一样

    3> block对外部变量的访问

    • 可以访问外部变量
    • 默认情况下,不能在block内修改外部变量
    • 用关键字__block修饰外部变量,就可以在block内修改它

    4> 用typedef定义block类型与函数类型

    1. 定义block类型

      ① 格式:typedef int (^myBlock)(int, int);
      ② myBlock是新的block类型的名字
      ③ myBlock前的int是block的返回值类型
      ④ myBlock后的小括号是形参列表
      
    2. 函数类型

      ① 格式:typedef int (*fun)(int, int);
      ② fun是新的函数类型的名字
      ③ fun前的int是函数的返回值类型
      ④ fun后的小括号是函数的形参列表
      

    5> 示例

    /*
     1.使用typedef定义分别一个block类型,一个指向函数的指针
     2.分别定义一个求和函数,用函数指针指向它
     3.用新的block类型定义一个求和的block
     4.定义一个输出一条横下的block
     5.分别用函数指针和block实现两个数的求和,中间输出一条横线
     */
    
    #import <Foundation/Foundation.h>
    
    //用typedef定义一个返回值类型为int,有两个int类型形参的block类型
    typedef int (^myBlock)(int, int);
    //用typedef定义一个返回值类型为int,有两个int类型形参的函数指针
    typedef int (*sumP)(int, int);
    
    //定义一个求和函数
    int sum(int a, int b)
    {
        return a + b;
    }
    
    int main()
    {
        //使用新的block类型定义一个求和的block
        myBlock sumBlock =^(int a, int b){
            return a + b;
        };
        //定义一个输出横线的block
        void (^lineBLock)() = ^{
            NSLog(@"--------------");
        };
        
        //使函数指针指向求和函数
        sumP p = sum;
        //通过block输出两个函数的和
        NSLog(@"%d", sumBlock(11, 12));
        //通过block输出一条横线
        lineBLock();
        //通过函数指针输出两个数的和
        NSLog(@"%d", sumBlock(11, 12));
        
        return 0;
    }
    

    二、protocol

    1> 基本使用

    1. 作用

      ① 声明一个方法列表,不能扩充成员变量
      ② 若一个类/协议遵守该协议,就会拥有该协议的方法列表
      ③ 可以使用@protocol 提前声明一个协议
      
    2. 定义

      ① 格式
      	@protocol MyProtocol < BaseProtocol >
      	  方法列表
      	@end
      	1)MyProtocol指定协议的名称
      	2)BaseProtocol指定该协议遵守的协议,通常遵守的是基协议,
      	  如:NSObject
      
      ② @required与@optional
      	1)@required:默认为该关键字,所定义的方法列表要求遵守该
      	  协议的类在实现文件中必须实现,不实现会发出警告
      	2)@optional:所定义的方法列表不要求遵守该协议的类实现
      

    2> 协议遵守

    1. 类遵守协议

      ① 格式
      	@interface Name:NSObject < MyProtocol >
      	@end
      	1)Name是类名,MyProtocol是协议名
      	2)Name类将拥有协议MyProtocol声明的所有方法
      
    2. 协议遵守协议

      ① 格式如协议的定义
      	1)MyProtocol协议将会拥有BaseProtocol协议中声明的所有方法
      

    3> @property的参数

    1. 作用

      ① 限制成员变量只能接受遵守某种协议的对象
      
    2. 格式

      ① @property (nonautomic, retain) id< MyProtocol > obj
      	1)MyProtocol限定obj只能接收遵守MyProtocol协议的对象
      	2)在相互引用的两个类中,retain参数在另一端要使用assign
      

    4> 协议与分类

    1. 协议

      ① 若为多个不相关的类扩充方法列表,通常使用协议
      ② 若父类遵守该协议,则子类也遵守该协议
      ③ 若一个协议只被一个类遵守,通常把该协议定义在该类中
      ④ 若一个协议被多个类遵守,通常把该协议定义在定义成单独的文件
      
    2. 分类

      ① 若为单个类或多个相互继承的类扩充方法列表,通常使用分类
      ② 若父类用有一个分类,则该类的子类也将拥有该分类
      ③ 分类通常定义在单独的文件中
      

    5> 协议的应用

    1. 代理模式

      ① 组成
      	1)抽象角色:通过接口或抽象类声明真实角色实现的业务方法
      	2)代理角色:实现抽象角色,是真实角色的代理,通过真实角色
      	  的业务逻辑方法来实现抽象方法,并可以附加自己的操作
      	3)真实角色:实现抽象角色,定义真实角色所要实现的业务逻辑,
      	  供代理角色调用
      ② 实例
      	1)主人委托保姆照顾孩子
      	2)老板委托秘书购买机票
      
    2. 协议在代理模式中的应用

      ① 通常情况下真是角色要定义自己的代理必须实现的规则
      ② 协议用来来实现代理所要遵循的规则
      ③ 遵循真实角色协议的对象,都可以作为真是角色的代理
      

    6> 示例(多文件)

    /******main.m文件******/
    #import <Foundation/Foundation.h>
    #import "Parent.h"
    #import "Children.h"
    #import "Nanny.h"
    
    int main()
    {
        @autoreleasepool {
            
            //定义一个Parent对象
            Parent *p = [[Parent alloc] init];
            //定义一个Children对象
            Children *c = [[Children alloc] init];
            //定义一个Nanny对象
            Nanny *n = [[Nanny alloc] init];
            
            //将对象p的属性Children初始化为c
            p.children = c;
            //将对象p的属性nanny初始化为n
            p.nanny = n;
            
            //调用对象p的takeCareTheChildren方法
            [p takeCareTheChildren];
            
        }
        return 0;
    }
    
    
    /******Parent.h文件******/
    #import <Foundation/Foundation.h>
    //
    #import "LookAfterTheChildren.h"
    //
    #import "Children.h"
    #import "Nanny.h"
    
    @interface Parent : NSObject
    
    //声明成员变量nanny,且限定其只能接收遵守LookAfterTheChildren协议的对象
    @property (nonatomic, strong) id<LookAfterTheChildren> nanny;
    //声明成员变量children
    @property (nonatomic, strong) Children *children;
    
    //定义方法,实现照顾children的功能
    - (void)takeCareTheChildren;
    
    @end
    /******Parent.m文件******/
    
    
    #import "Parent.h"
    @implementation Parent
    
    //
    - (void)takeCareTheChildren
    {
        //委托代理nanny来完成照顾children的任务
        [_nanny feedTheChildren];
        [_nanny playWithTheChildren];
    }
    
    @end
    
    
    /******Children.h文件******/
    #import <Foundation/Foundation.h>
    
    @interface Children : NSObject
    @end
    
    
    /******Children.m文件******/
    #import "Children.h"
    
    @implementation Children
    
    @end
    
    
    /******Nanny.h文件******/
    #import <Foundation/Foundation.h>
    //
    #import "LookAfterTheChildren.h"
    
    //要想成为Parent的代理,必须遵守LookAfterTheChildren协议
    @interface Nanny : NSObject<LookAfterTheChildren>
    
    @end
    
    
    /******Nanny.m文件******/
    #import "Nanny.h"
    
    @implementation Nanny
    
    //实现LookAfterTheChildren协议的方法,具备照顾children的能力
    - (void)feedTheChildren
    {
        NSLog(@"喂孩子吃饭");
    }
    - (void)playWithTheChildren
    {
        NSLog(@"陪孩子玩耍");
    }
    
    @end
    
    
    /******LookAfterTheChildren.h文件******/
    #import <Foundation/Foundation.h>
    
    //由Parent定义的协议,声明照顾children的方法列表
    @protocol LookAfterTheChildren <NSObject>
    
    //给children喂饭的方法
    - (void)feedTheChildren;
    //陪children玩耍的方法
    - (void)playWithTheChildren;
    
    @end
    
  • 相关阅读:
    canvas+js绘制序列帧动画+面向对象
    canvas+js画饼状图
    CSS3 文本溢出问题
    jquery 实现省市二级联动
    jquery将json数据放入表格当中
    css ie6双倍margin现象
    css margin塌陷问题
    css ie浏览器兼容问题
    css 实现文字图片垂直对齐
    css 清楚浮动三种方法
  • 原文地址:https://www.cnblogs.com/theDesertIslandOutOfTheWorld/p/4731676.html
Copyright © 2020-2023  润新知