【黑马程序员】-oc中的block和protocol

------- <ahref="http://www.itheima.com" target="blank">android培训</a>、<ahref="http://www.itheima.com" target="blank">java培训</a>、期待与您交流! ----------

一. Block类型

block类型封装了一段代码,可以在任何时候执行,而且此段代码是在程序运行过程中保存起来的。

block的标志为:^

block基本定义形式为:

                  返回值类型   (^名字)(参数类型) = ^(形参){

                         代码区

                   };

void (^sumBlock)() = ^{
        return a+b;
    };

block跟函数很像:

(1)可以保存代码;

(2)有返回值;

(3)有形参;

(4)调用方式一样;

(5)写在主函数之中。

此处复习一下函数指针:

int main()
{
    int (*p)(int, int, int *) = sumAndMinus;
}

int sumAndMinus(int a, int b, int *minus)
{
    //函数指针的用法复习;
    *minus = a - b;
    
    return a+b;
}

2. 带返回值和参数的block

定义方式为:

    int (^sumBlock)(int, int) = ^(int a, int b){
        return a+b;
    };

          此处注意,在block没有形参时,可以省略后边的“()”。在以后的学习中,指向函数的指针一般都用block来替代。

3.block总结:

(1)block访问外部变量:

         1> block内部可以访问外面的变量;

         2> 默认情况下,block内部不能访问修改外面的局部变量;

         3> 给局部变量加上_block关键字,这个局部变量就可以在block内部修改。

4. 如何利用block封装

(1)  ^(int a, int b){.......

             };

(2)  ^ {........

         };

5. 利用typedef定义block类型

          typedef    int (^ MyBlock)(int , int);

          MyBlock    b1, b2;

          为变量赋值的方法:

#import <Foundation/Foundation.h>

typedef int (^MyBlock)(int, int);

int main()
{
    //改进写法;
    MyBlock sumBlock = ^(int a, int b){
        return a+b;
    };
    
    MyBlock b1;
    b1 = ^(int a, int b){
        return a+b;
    };
    return 0;
}
. protocol协议

1. 定义方法:

@protocol   协议名称

@end

2. 基本使用:

(1)可以用来声明一大堆方法(不能声明成员变量);

(2)只要某个类遵守了这个协议,就相当于拥有这个协议所包含的所有方法声明(注意这里仅仅是声明,而具体的实现要通过 @implementation里实现)。

(3)父类遵守协议,子类也就遵守这个协议。

3.协议中也可以加入限制

(1)@required:必须要求实现,默认为这种情况。

(2)@optional:可选择实现。

4. 在协议遵守时,可以同时遵守多个协议。例如同时遵守两个协议:

             @interface   Person:NSObject    <MyProtocol, MyProtocol 1>

             @end

5. 基协议

        就像NSObject是一个基类一样,所有的协议也是基于另一个协议的。也有一个基协议为NSObject。

#import <Foundation/Foundation.h>

//定义了一个名为MyProtocol的协议
@protocol MyProtocol <NSObject>

//需要实现,默认
@required

//可选实现
@optional

@end
    基类遵守基协议,因此在写协议时,一定要写上NSObject。

6. 定义一个变量同时,可以限制它遵守某个协议

   类名<协议名称>   *变量名称;

   id<协议名称>       变量名称;

    NSObject *obj = [[NSObject alloc] init];
    
    NSObject *obj1 = @"123413"; //多态
    
    NSObject<MyProtocol> *obj3 = [[NSObject alloc] init];

7. 协议声明

       就像在@class一样,可以通过@protocol    名称;

       但是在.m文件中还要利用#import 头文件  来声明。在.h文件中要用到这个类,仅仅利用@告诉它就可以了,不用管里边存放的内容。

8. @property 中声明的属性可以做一个遵守协议的限制

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

10. 代理设计模式

     直接利用代码来表示:

#import <Foundation/Foundation.h>
#import "TicketAndNumber.h"
#import "Person.h"
#import "Agent.h"
#import "NewAgent.h"

int main()
{
    Person *p = [[Person alloc] init];
    
    Agent *agent = [[Agent alloc] init];
    
    p.delegate = agent;
    
    [p buyTicket];
    
    NewAgent *na = [[NewAgent alloc] init];
    
    p.delegate = na;
    
    [p buyTicket];
   
    return 0;
}

#import <Foundation/Foundation.h>
#import "TicketAndNumber.h"

@class Agent;

@interface Person : NSObject

- (void)buyTicket;

@property(nonatomic, strong) id<TicketAndNumber> delegate;

@end

#import "Person.h"

@implementation Person

- (void)buyTicket
{
    //利用代理来询问票价和剩余票数
    double price = [_delegate ticketPrice];
    int    num = [_delegate ticketNumber];
    
    NSLog(@"询问的票价为:%f, 票数为:%d", price, num);
}

@end

#import <Foundation/Foundation.h>
@protocol TicketAndNumber;

@interface Agent : NSObject <TicketAndNumber>

@property(nonatomic, strong)NSString *name;

@end

#import "Agent.h"
#import "TicketAndNumber.h"

@implementation Agent

- (double)ticketPrice
{
    return 1000.0;
}

- (int)ticketNumber
{
    return 12;
}

@end

#import <Foundation/Foundation.h>

@protocol TicketAndNumber <NSObject>

@required
- (double)ticketPrice;
- (int)ticketNumber;

@optional

@end

#import <Foundation/Foundation.h>
#import "TicketAndNumber.h"
//@protocol TicketAndNumber;

@interface NewAgent : NSObject <TicketAndNumber>

@property(nonatomic, strong)NSString *name;

@end

#import "NewAgent.h"
//#import "TicketAndNumber.h"

@implementation NewAgent

- (double)ticketPrice
{
    return 100.0;
}

- (int)ticketNumber
{
    return 1;
}

@end

------- <ahref="http://www.itheima.com" target="blank">android培训</a>、<ahref="http://www.itheima.com" target="blank">java培训</a>、期待与您交流! ----------


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值