zoukankan      html  css  js  c++  java
  • OC基础 代理和协议

    OC基础 代理和协议

    1.协议

    (1)oc语言中得协议:一组方法列表,不需要我们自己实现,由遵守协议的类来实现协议所定制的方法。

    (2)协议的使用步骤:制定协议-->遵守协议-->实现协议-->调用协议。

    (3)协议声明的关键字:

    (a)@required,必须实现,不实现的话在.m文件内会报警告。

    (b)@optional,可选实现,不实现的话在.m文件内也不会报警告。

    (4)协议和继承的区别:

    (a)相同之处:都可以规范统一类中的方法。

    (b)不同之处:继承的子类不需要再实现一遍父类的方法(除非有父类的方法不能够走子类的需求),子类可以继承父类的成员变量。协议之中只能有方法,不能有成员变量。

    测试例子:以公司招程序员为例,公司制定的协议:必须会写代码,调bug,汇报工作。另外特别要求会唱歌。

    制定两个协议,分别是Coder和Art协议:

    #import <Foundation/Foundation.h>
    
    @protocol Coder <NSObject>
    
    //必须实现的协议
    @required
    - (void)code;
    - (void)debug;
    - (void)report;
    
    //可以选择是否实现的协议
    @optional
    - (void)playGame;
    
    @end
    #import <Foundation/Foundation.h>
    
    @protocol Art <NSObject>
    //注意:如果不写协议关键字,默认是@required
    - (void)singing;
    
    @end

    公司类Company,Company.h和Company.m文件:

    #import <Foundation/Foundation.h>
    #import "Coder.h"
    
    @interface Company : NSObject
    
    @end
    #import "Company.h"
    
    @implementation Company
    
    @end

    员工类Staff,Staff.h文件:

    #import <Foundation/Foundation.h>
    #import "Company.h"
    #import "Art.h"
    //遵守协议:在需要实现协议的类里面的父类后面<协议名>,如果有多个,协议之间用逗号隔开。
    @interface Staff : NSObject<Coder,Art>
    
    @end

    Staff.h文件:

    #import "Staff.h"
    
    @implementation Staff
    //实现协议
    - (void)code {
        NSLog(@"我会写代码");
    }
    
    - (void)debug {
        NSLog(@"我会调试代码");
    }
    
    - (void)report {
        NSLog(@"我还会汇报我的工作");
    }
    
    - (void)singing {
        NSLog(@"我会唱歌哦");
    }
    
    
    @end

    测试:

    #import <Foundation/Foundation.h>
    #import "Staff.h"
    
    int main(int argc, const char * argv[]) {
        @autoreleasepool {
            
            //协议的步骤
            //1,制定协议:两种方式,一个是生成协议文件,另外一个直接在制定协议的类里面写协议的代码
            //2,遵守协议:在需要实现协议的类里面的父类后面<协议名>
            //3,实现协议:在需要实现协议的类的.m文件里面实现协议制定的方法(记得不要在.h文件里面重新声明协议制定的方法).
            //4,调用协议.
    
            Staff *staff = [[Staff alloc] init];
            [staff code];
            [staff debug];
            [staff report];
            [staff singing];
            
            //要判断是否有playGame方法存在,存在就执行,否则不执行。
            //这里playGame没有实现,所以不会执行。
            if ([staff respondsToSelector:@selector(playGame)]) {
                [staff playGame];
            }
            
        }
        return 0;
    }

    测试结果:

    2.代理

    代理:A类想去做一件事,但是A类不会做或者不直接做,而是委托B类去做,A委托B做,B就是A的代理。这种模式就叫做代理。

    测试例子:这是一个程序员委托朋友找女朋友的故事。

    协议(也就是程序员的要求)

    #import <Foundation/Foundation.h>
    
    //制定协议
    @protocol FindGirl <NSObject>
    
    - (void)isGirl;
    - (void)beautiful;
    - (void)gentle;
    
    @end

    程序员类Programmer,Programmer.h文件:

    #import <Foundation/Foundation.h>
    #import "FindGirl.h"
    
    @interface Programmer : NSObject
    
    @property (nonatomic,retain) id<FindGirl>delegate;
    
    - (void)find;
    
    @end

    Programmer.m文件:

    #import "Programmer.h"
    
    @implementation Programmer
    
    - (void)find {
        [self.delegate isGirl];
        [self.delegate beautiful];
        [self.delegate gentle];
    }
    
    @end

    朋友类Friend,Friend.h文件:

    #import <Foundation/Foundation.h>
    #import "FindGirl.h"
    
    @interface Friend : NSObject<FindGirl>
    
    @end

    Friend.m文件:

    #import "Friend.h"
    
    @implementation Friend
    
    - (void)isGirl {
        NSLog(@"首先她得是个妹子");
    }
    
    - (void)beautiful {
        NSLog(@"其次这个妹子要漂亮");
    }
    
    - (void)gentle {
        NSLog(@"最后她要温柔的哦");
    }
    
    @end

    测试:

    #import <Foundation/Foundation.h>
    #import "Programmer.h"
    #import "Friend.h"
    
    int main(int argc, const char * argv[]) {
        @autoreleasepool {
            
            //Programmer是委托者,Friend是代理者
            //代理实现的步骤
            //1,定义委托者和代理者2个类
            //2,制定协议
            //3,代理者遵守协议和实现协议
            //4,创建代理者对象和委托者对象,并且指定委托者的代理对象
            //5,调用代理(在委托者里面调用)
            
            Programmer *programmer = [[Programmer alloc] init];
            Friend *friend = [[Friend alloc] init];
            
            //friend遵守programmer的协议
            programmer.delegate = friend;
            [programmer find];
            
        }
        return 0;
    }

    测试结果:

    这里需要注意一下,我们可以把协议写到委托者里面,这样比较简洁。上面的例子可以把FindGirl协议,写到委托者(程序员)Programmer里面。代码如下:

    #import <Foundation/Foundation.h>
    
    @protocol FindGirl <NSObject>
    
    - (void)isGirl;
    - (void)beautiful;
    - (void)gentle;
    
    @end
    
    @interface Programmer : NSObject
    
    @property (nonatomic,retain) id<FindGirl>delegate;
    
    - (void)find;
    
    @end

    3.循环引用

    循环引用:就是多个对象之间相互引用,形成环状。

    例子:People1帮People2做事,People2帮People1做事。

    制定协议:People1Delegate和People2Delegate

    #import <Foundation/Foundation.h>
    
    //制定People1的协议
    @protocol People1Delegate <NSObject>
    
    - (void)people1Required;
    
    @end
    #import <Foundation/Foundation.h>
    
    //制定People2的协议
    @protocol People2Delegate <NSObject>
    
    - (void)people2Required;
    
    @end

    People1类,People1.h文件:

    #import <Foundation/Foundation.h>
    #import "People1Delegate.h"
    #import "People2Delegate.h"
    
    //实现协议,代表能够做某事
    @interface People1 : NSObject<People2Delegate>
    
    //实现协议的对象指针,代表要求别人做某事
    //注意:这里属性的修饰不能使用retain,只能使用weak或assign,如果使用retain就会造成循环引用的问题
    @property (nonatomic, weak) id<People1Delegate> delegate;
    
    - (void)people1Working;
    
    @end

    People1.m文件:

    #import "People1.h"
    
    @implementation People1
    //People1实现People2的协议
    - (void)people2Required {
        NSLog(@"帮people2做事");
    }
    
    - (void)people1Working {
        //调用代理的方法(通知代理对象去做某事)
        [self.delegate people1Required];
    }
    
    @end

    People2类,People2.h文件:

    #import <Foundation/Foundation.h>
    #import "People1Delegate.h"
    #import "People2Delegate.h"
    
    @interface People2 : NSObject<People1Delegate>
    
    @property (nonatomic, weak) id<People2Delegate> delegate;
    
    - (void)people2Working;
    
    @end

    People2.h文件:

    #import "People2.h"
    
    @implementation People2
    
    - (void)people1Required {
        NSLog(@"帮people1做事");
    }
    
    - (void)people2Working {
        [self.delegate people2Required];
    }
    
    @end

    测试:

    #import <Foundation/Foundation.h>
    #import "People1.h"
    #import "People2.h"
    
    int main(int argc, const char * argv[]) {
        @autoreleasepool {
            
            People1 *people1 = [[People1 alloc] init];
            People2 *people2 = [[People2 alloc] init];
            
            people1.delegate = people2;
            [people1 people1Working];
            
            people2.delegate = people1;
            [people2 people2Working];
            
            
        }
        return 0;
    }

    测试结果:

  • 相关阅读:
    linux系统安装Mysql
    makefile通用模板
    makefile常用函数
    mysqlconnector安装
    linux添加默认路由route
    .h文件与.hpp文件的区别
    ubuntu20优化开机启动
    [javascript]js原型链以及原型链继承
    webpack4.*入门笔记
    图像编程:图片大小关系
  • 原文地址:https://www.cnblogs.com/DWdan/p/5095462.html
Copyright © 2011-2022 走看看