黑马程序员—Objective-C学习—block和protocol

本文深入探讨Java编程中block的使用与协议定义,通过实例展示了如何定义、封装及访问外部变量,同时介绍了如何利用协议实现多态性,并提供了详细的操作步骤与代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

------ Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------

一、block

1、block用来保存一段代码
       block的标志 : ^
2、 block跟函数很像:
a、可以保存代码
b、有返回值
c、有形参
d、调用方式一样
3、 如何定义block变量:和指向函数的指针很像
int (^sumBlock)(int, int);
void (^myBlock) ();
2、 如何利用block封装代码

 ^(int a, int b){

 return a + b;

 };

 ^(){

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

 };

 ^{

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

 };

3 block访问外面变量
a、 block内部可以访问外面的变量
b、默认情况下,block内部不能修改外面的局部变量
c、给局部变量加上_block关键字, 这个局部变量就可以在block内部修改
4、 利用typedef定义block类型

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

 // 以后就可以利用MyBlock这种类型来定义block变量

    MyBlock b1,b2;

    b1 = ^(int a, int b){

        return a - b;

    };

    MyBlock sumBlock = ^(int a, int b){

        return a + b;

};

#import <Foundation/Foundation.h>


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


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

{

    MyBlock sumBlock = ^(int a, int b){

        return a + b;

    };

    

    MyBlock minusBlock = ^(int a, int b){

        return a - b;

    };

    

    MyBlock multiplyBlock = ^(int a, int b){

        return a * b;

    };

    

    NSLog(@"%d - %d - %d",sumBlock(12,6), minusBlock(15,3), multiplyBlock(15, 3));

    

    return 0;

}


// 没有返回值,没有形参的block

void test()

{

    // block用来保存一段代码

    // block的标志 ^

    /*

     block跟函数很像:

     1、可以保存代码

     2、有返回值

     3、有形参

     4、调用方式一样

     */

    // 定义block变量

    

    // 如果block没有形参,可以省略后面的()

    void (^myBlock) () = ^{

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

    };

    

    // 判断block变量调用block内部的代码

    myBlock();

}


// 有返回值、有形参的block

void test2()

{

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

        return a + b;

    };

    

    int c = sumBlock(4, 5);

    

    NSLog(@"%d",c);

    

    // 用一个block输出N条横线

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

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

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

        }

    };

    lineBlock(5);

}


void test3()

{

    int a =10;

    __block int b = 20;

    

    void (^block)();

    

    block = ^{

        // block内部可以访问外面的变量

        NSLog(@"a = %d",a);

        

        // 默认情况下,block内部不能修改外面的局部变量

        // a = 20;

        

        // 给局部变量加上__block关键字, 这个局部变量就可以在block内部修改

        b = 25;

    };

    

    block();

}

二、protocol

1、基本用途:声明一大堆方法(不能声明成员变量),只要一个类遵守了某一份协议,就拥有了这份协议中的所有方法声明

2、 协议的定义

 @protocol 协议名称 <NSOject>

 // 方法的声明列表...

 @end

<NSObject> 是基协议。

2、如何遵守协议

a、一个类遵守协议

@interface 类名 : 父类名 <协议名称>

@end

b、协议遵守协议

@protocol 协议名称 <其他协议名称1,其他协议名称2>

@end

只要父类遵守了某个协议,就相当于子类也遵守了

3、协议中方法声明的关键字

a、@required 要求实现,如果没有实现就会发出警告(默认)

b、@optional 不要求实现,怎样都不会警告

4、定义一个变量的时候,限制这个变量保存的对象遵守某个协议

a、类名<协议名称> *变量名;    例如:NSObject<MyProtocol> *obj;

b、id<协议名称> 变量名;   例如:id<MyProtocol> obj2;

如果没有遵守对应的协议,编译器会警告

5@property中声明的变量也可用做一个遵守协议的限制

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

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

@property (nonatomic, strong) Dog<MyProtocol> *dog;

@property (nonatomic, strong) id<MyProtocol> dog1;

6、协议的提前声明@protocol 协议名称,和@class 类名一个原理声明在用到它的.h文件中

7、协议可以定义在单独.h文件中,也可以定义在某个类中

a、如果这个协议只用在某个类中,应该把协议定义在该类中

b、如果这个协议用在很多类中,就应该定义在单独文件中

8、分类可以定义在单独.h.m文件中,也可以定义在原来类中

a、一般情况下,都是定义在单独文件中

b、定义在原来类中的分类,只要求能看懂语法

MyProtocol.h

#import <Foundation/Foundation.h>

// 定义了一个名叫MyProtocol的协议

@protocol MyProtocol <NSObject>

//@required 要求实现,不实现就会发出警告

//@optional 不要求实现

- (void)test4;

@required // 默认@required

- (void)test; 

- (void)test2; 

@optional

- (void)test3; 

@end

MyProtocol2.h

#import <Foundation/Foundation.h>


@protocol MyProtocol2 <NSObject>

- (void)haha; 

@optional

- (void)haha1;

@end

MyProtocol3.h

// 一个协议遵守了另外一个协议,就可以拥有另外一个协议的所有方法声明


@protocol MyProtocol3 <MyProtocol>

- (void)hehe;

@end

Person.h

#import <Foundation/Foundation.h>

// #import "MyProtocol3.h"

@class Hashiq;

@protocol MyProtocol2 ;

@protocol MyProtocol3 ;

// 只要一个类遵守了某一份协议,就能拥有这份协议中的所有方法声明

// : 继承

// <>遵守协议

@interface Person : NSObject <MyProtocol3, MyProtocol2>


@property (nonatomic, strong) id<MyProtocol2> obj;

@property (nonatomic, strong) Hashiq *hashiq; 

@end

Person.m

#import "Person.h"

#import "MyProtocol2.h"

#import "MyProtocol3.h"

@implementation Person


- (void)test

{

}

- (void)test2

{

}

- (void)test4

{

}

- (void)haha

{

}

- (void)hehe

{

}

@end

Dog.h

#import <Foundation/Foundation.h>

@protocol MyProtocol2

@interface Dog : NSObject <MyProtocol2>

@end

Dog.m

#import "Dog.h"

#import "MyProtocol2.h"

@implementation Dog


- (void)haha

{

}

@end

Hashiq.h

#import "Dog.h"

@interface Hashiq : Dog

@end

Hashiq.m

#import "Hashiq.h"

@implementation Hashiq

@end

main.m

#import <Foundation/Foundation.h>

#import "MyProtocol.h"

#import "Person.h"

#import "MyProtocol3.h"

#import "Dog.h"

#import "Hashiq.h"


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

{

    Person *p = [[Person alloc] init];

    p.obj =[[Dog alloc] init];

    p.obj =[[Hashiq alloc] init]; 

    return 0;

}


void test()

{

    NSObject *obj = [[NSObject alloc] init]; 

    NSObject *obj2 = @"sf23kfs"

    // 要求obj3保存的对象必须是遵守MyProtocol这个协议 

    // NSObject<MyProtocol> *obj3 = [[NSObject alloc] init]; // [[NSObject alloc] init]是没有遵守Myprototol协议的 

    NSObject<MyProtocol> *obj3 = [[Person alloc] init]; 

    obj3 = nil

    id<MyProtocol> obj4 = [[Person alloc] init]; 

    obj4 = nil

    // 需求obj5,保存的对象必须遵守MyPrototol3、并且继承了Person

    Person<MyProtocol3> *obj5 = [[Person alloc] init];

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值