• Delegate 代理委托 +block+类别Category


    1.协议  代理模式

    两个对象之间如何传递数据

    同一时间只完成一件事情

     一般把协议写在代理中

    接受的类型用id并且服从协议(@property(nonatomic ,assign)id<agentDelegate>delegate

    一定要确保对象实现了方法

    例如:我需要刷新一个数据,可是我访问不到,而viewcontroller可以,我就发布协议,即写一个代理.

    @class Footview;//因为代理写在@interface之前,所以要先声明Footview

    @protocol 协议名称FootviewDelegate <NSObject>

    @required   //必须实现

                     //刷新数据方法的声明

    -(void)FootviewReloaddata:(footview *)footview;//一般以协议名字开头,必须传入自身控件为第一参数;

    @end

    @interface  footview :UIview

    @property (nonatomic,weak) id<FootviewDelegate> delegate;

    @end

    在需要刷新数据的地方:

    //先判断代理是否实现 ,若实现了,直接调用

    if([self.delegate respondsToSelected(footerviewloaddata:)]){

      [self.delegate footViewloaddata:self];

    }

    在viewcontroller 中 先创建FootView,并服从协议, self.delegate = self,实现具体方法;

    1.Protocol:声明方法,不能实现。Protocol里面的方法,可以让任何类实现,只要服从协议。Protocol就是协议。只要遵守了协议就拥有了,协议里 的所有方法声明。

    c,协议方法声明中的关键字

    1)required 要求实现,若没有实现则警告,不报错

    2)Optional不要求实现

    2.父类遵守了某个协议,子类也遵守。

    3.OC不能继承多个类,但是可以遵守多个协议。继承类(:),遵守协议(<>).

    4.协议可以遵守协议,一个协议遵守了另一个协议,就拥有另一个协议的方法声明。

    a,协议的定义

    @protocol 协议名称 <NSObject>

    //方法的声明

    @end

    b,如何遵守协议

    类遵守协议

    @protocol 类名:父类名<协议1,协议2>

    @end

    协议遵守协议

    @protocol 协议名字<其他协议名>

    @end

    d,定义变量时遵守协议的限制

    类名<协议名称>*变量名 NSObject<Myprotocol>*obj;

    Id<协议名称>变量名  id<Myprotocol>obj1;

    e,Property中声明的属性可以遵守协议的限制

    @property(nonatomic,strong)类名<协议名称>*属性名;

    @Property(nonatomic,strong)id<协议名称>*属性名;

    例子:老板让秘书找中介租房,并通过QQ,微信或者电话通知老板结果。

    f,协议本身写在.h文件里面,也可以定义在任何地方,当协议只有在这个类遵守时,一般把协议写在类里面,若这个协议需要多个类去实现,就可以外面单独的文件里。

    1.中介的代理内容

    #import <Foundation/Foundation.h>

    @protocol RentHouseDelegate <NSObject>

    -(void)useQQ:(NSString *)message;

    -(void)usetel:(NSString *)telephone;

    -(void)useweChat:(NSString *)weChat;

    @end

    @interface Agent : NSObject

    @property (nonatomic,assign) id <RentHouseDelegate> delegate;

    -(void)rentHouse;

    @end

    实现:

    #import "Agent.h"

    @implementation Agent

    -(void)rentHouse{

        if ([self.delegate respondsToSelector:@selector(useQQ:)]) {

            [self.delegate useQQ:@"找到房子了"];

        }

        if ([self.delegate respondsToSelector:@selector(useweChat:)]) {

            [self.delegate useweChat:@"微信找到房子了"];

        }

        if ([self.delegate respondsToSelector:@selector(usetel:)]) {

            [self.delegate usetel:@"电话找到房子了"];

        }

    }

    @end 

    2.秘书类服从代理,调用中介的联系方法。

    #import <Foundation/Foundation.h>

    #import "Agent.h"

    @interface Secretary : NSObject<RentHouseDelegate>

    @end

    #import "Secretary.h"

    @implementation Secretary

    -(void)useQQ:(NSString *)message{

        NSLog(@"%@",message);

    }

    -(void)usetel:(NSString *)telephone {

        NSLog(@"%@",telephone);

    }

    -(void)useweChat:(NSString *)weChat{

        NSLog(@"%@",weChat);

    }

    @end

    3.老板需求

    #import <Foundation/Foundation.h>

     @interface Boss : NSObject

    -(void)needHouse;

    @end

    #import "Boss.h"

    #import "Agent.h"

    #import "Secretary.h"

    @implementation Boss

    -(void)needHouse{

        Agent *xiaowang = [[Agent alloc]init];

        Secretary *lisi = [[Secretary alloc]init];

        xiaowang.delegate = lisi;

        [xiaowang rentHouse];

    }

    @end

    4.main函数调用

    #import <Foundation/Foundation.h>

    #import "Boss.h"

    int main(int argc, const char * argv[]) {

        @autoreleasepool {

            Boss *zhangsan = [[Boss alloc]init];

            [zhangsan needHouse];

        }

        return 0;

    }

    2.Block

    block 的标识符^

    a,定义block变量

    Int (^SumBlock)(int,int)//有参数,返回值为int

            定义一个block类型的变量,接收两个参数,做加法运算

            int (^Sumblock)(int a,int b) = ^(int a,int b){

                return a+b;

            };

            NSLog(@"%d",Sumblock(1,2));

            return 0;

    Void (^Myblock)()//无参数,返回值类型为空

            定义一个block类型的变量,打印n条线

                    void(^Myblock)(int)= ^(int n){

                        for (int i = 0; i< n ; i++) {

                            NSLog(@"----------");

                        }

                    };

                    Myblock(3);

                }

    b,Block访问外部变量

    Block内部可以访问外部变量,默认情况下,Block内部不能修改外部的局部变量。给局部变量加上__block关键字,则这个局部变量可以在block内部进行修改。

    c,利用typedef定义block类型,

    Typedef int (^MyBlock)(int ,int);

    3.Category 类别

    1、什么是类别

    在已有类的基础之上无需子类化,直接给类添加一些方法

    a.继承与类别的区别

    继承不仅可以添加一些方法,还可以添加一些属性

    类别只能添加方法

    b.在使用的时候继承必须创建一个对象再去调用方法,使用类别里面的方法和原有类的使用方式一致

    c,类别不会改变现有类的方法,万一重名,自己写的优先级最高

  • 相关阅读:
    boost json序列化
    boost serialize序列化
    lambda详解
    未知的生成错误““clr-namespace: test”mapping URI 无效
    无法解析的外部符号 "public: static void __cdecl std::_String_base::_Xran(void)" (?_Xran@_String_base@std@@SAXXZ)"
    LINK : fatal error LNK1123: 转换到 COFF 期间失败: 文件无效或损坏
    事实证明:软件层次的操作可以毁掉硬件
    下载随书源码的好地方
    一道简单的题目(东财)
    VS2013破解
  • 原文地址:https://www.cnblogs.com/yangqinglong/p/5075246.html
Copyright © 2020-2023  润新知