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

来源:互联网 发布:要知苦乐法是什么意思 编辑:程序博客网 时间:2024/06/05 08:46
------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>


typedefint (^MyBlock)(int,int);


int main(int argc, constchar * 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));

    

   return0;

}


//没有返回值,没有形参的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;

   __blockint 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"

@classHashiq;

@protocolMyProtocol2 ;

@protocolMyProtocol3 ;

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

// :继承

// <>遵守协议

@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>

@protocolMyProtocol2

@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, constchar * argv[])

{

   Person *p = [[Personalloc]init];

    p.obj =[[Dogalloc]init];

    p.obj =[[Hashiqalloc]init]; 

   return0;

}


void test()

{

   NSObject *obj = [[NSObjectalloc]init]; 

   NSObject *obj2 =@"sf23kfs"

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

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

   NSObject<MyProtocol> *obj3 = [[Personalloc]init]; 

    obj3 =nil

   id<MyProtocol> obj4 = [[Personalloc]init]; 

    obj4 =nil

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

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

}

0 0