您的位置:首页 > 职场人生

黑马程序员------OC block(代码块)和protocol(协议)

2015-08-01 21:14 706 查看
------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ------
一、block代码块

1.block类型是一个c级别的语法和运行机制,他与标准c函数类似,不同之处在于,它除了有可执行代码以外,还包含了与堆。栈 内存绑定的变量,因此block 对象包含着一组状态数据,这些数据在程序执行是用于对行为产生影响,block被设计为可同时兼容 三种语言 oc 、c++ 、c。

block 的基本使用

int(^myBlock )(int)=(int num){ return }

1) 无参 无返回值

定义一个没有参数\没有返回值的block变量,同时赋值。

void (^block变量名)()=^(){

代码块的语句

}

void (^myBlock1)(int)=^( ){

NSLog(@"xxxx");

}

//使用block变量

myBlock1(); //这样就打印xxxxx 没参数^小括号可以省略

2)有参数无返回值

void(^变量名)(参数类型及个数)=^(形参列表){

代码块语句

}

viod (^myBlock2)(int,int)=^(int a, int b){

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

}

myBlock2(3,6);

//先定义变量,再赋值

myblock2=^(int x,inty){

NSLog(@"x*y =%d",x*y);

}

3)有参数有返回值

定义一个有从哪回溯有返回值的block

int(^myBlock3)(int,int)=^(intx,inty){

return x+y;

}

//使用block ,接受返回值

int sum =myBlock3 (23,45 );

//重新给变量赋值

myblock3=^(int x,inty){

return x*y;

}

2.block的typedef

利用typedef定义的block类型(和指向函数的只注重很像)

typedef void(^myBlock)() :

格式 : typedef 返回值类型(^新别名)(参数类型列表)

typedf int (^myBlock1)(int ,int);

给没有返回值,没有参数的block起一个别名

myblock是一个类型不在是一个单纯的变量

typedef void (^myblock)();

myblock f1;

//block类型的变量

f1 =^{

NSLog(@“hellowworld");

}

//使用

f1();

定义有参数 \有返回值的block类型

int (^block1)(int,int)=^(inta,intb){

return a=b;

}

定义了一个block1的类型 返回值是int 有两个int类型参数

typedef int(^block1)(int,int);

block1 b1;

b1 =^(int x,int y){

return x-y;

}

int s= b1(2,3);

连续定义多个 block1类型的变量

block1 n,n2,n2;

3.block 访问外部变量

1)在block内部可以访问外部的变量

当定义block的时候会把外部变量以const 的方式复制一份,存放到block的所在内存中

2)block内部不可以修改外部的变量值

3)__block 修饰的变量 内部可以修改 应为这里不再以const的方式拷贝

4.注意:

1)静态变量和全局变量。在不加 __block 都会直接引用变量地址,也就意味着可以修改变量的值,在没有__block参数的情况下

2)全局变量block:定义在函数外部的block是global 另外如果函数内部的block,但是没有捕捉任何自动变量,那么他也是全局的

3)栈block 区别,是否引用了外部变量

4)堆block 则是对栈block copy得来,对全局block copy不会有任何作用,返回的依然是全局block。

5.block作为函数的返回值

步骤 1.使用typedef定义一个新类型

//给block起个别名

typedef int (^newType)(int num1,int num2);

2.使用新类型作为函数的返回值

//定义一个返回值是block类型的函数

newType test4(){}

3.定义变量接受函数的返回值(block类型)

4.调用block

//block类型作为函数的返回值

newType test(){

newType w1 =^{

NSLog(@"xxxx");

NSLog(@"helloword");

}

return w1;//返回值

}

//定义block类型的变量 接受函数返回的结果

newType n1 =test();

//执行block

n1();

//重新定义一个新的类型 newType2

typedef int (^newType2)(int,int);

newType2 test2 {

return^(int a,int b){

return a+b;

}

}

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

newType2 n2 = test2();

//调用block

int s = (23,23);

7.block的掌握技巧

1)block 结构的快速提示: 输入inlineBlock

2)我们在定义block变量的时候,形参类型及个数 这个位置处可以加上形参名

test(^int(int,int)){}

实现程序员工作
#import <Foundation/Foundation.h>

//block类型的变量 workBlock 作为函数的参数
void work( void(^workBlock)() ){

NSLog(@"起床刷牙");
NSLog(@"去车站");
NSLog(@"坐车");

workBlock();//打印其它的

NSLog(@"去车站");
NSLog(@"坐车回家");
NSLog(@"吃饭");
NSLog(@"睡觉");

}
void workday(int n){
typedef void(^workBlock) ();
workBlock w;
switch (n) {
case 1:
w=(^{
NSLog(@"了解项目");
});
break;
case 2:
w=(^{
NSLog(@"了解项目");
});
break;
case 3:
w=(^{
NSLog(@"了解项目");
});
break;
case 4:
w=(^{
NSLog(@"了解项目");
});
break;
case 5:
w=(^{
NSLog(@"离职");
});
break;

default:
break;
}
//调用函数
work(w);

}

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

workday(5);

return 0;

}
}


二、protocol(协议)

1.protocol 概念及基本使用

什么是协议:一些方法的声明 ,一般写到一个.h头文件中

方法有两种:必须实现的 和选择实现的

协议的作用: 供其他的类区遵守

如果一个类遵守了一个协议,就应该实现这个协议宏定义的必须要实现的方法。

2. 如何定义一个协议

@protocol xxx <NSObject> 默认的情况下遵守的 NSObject 协议

@end

类遵守协议的格式

1)遵守协议

先导如入头文件

@interface Person :NSObject <xxx>;

@end

2)遵守多个协议

@interface 类名:NSObject <xxx,aaa ,bbb>;

@end

#import <Foundation/Foundation.h>

//定义一个协议

//定义协议的流程-->定义协议-->让类遵守这个协议-->实现协议中对应的方法(必须要实现的)

@protocol basepProtocol <NSObject>

//声明一些方法

-(void)eat;

-(void)run;

@end

//Person 遵守这个协议

@intrface Person :NSObjeect <baseProtocol>

@end

@implementation Person

-(void)eat{

NSLog(@"人在吃法饭");

}

-(void)run{

NSLog(@"人在跑步");

}

@end

当我们遵守了某个协议后,就有相当于这个类有了协议中所有的方法声明

3.protocol的其他用法

protocol的使用注意

1)protocol :就一个用途,用来声明一大堆的方法(不能声明成员变量),不能写实现

2)只要某个类遵守了这个协议,就拥有了这个协议中的所有方法

3)只要父类遵守了某个协议,那么子类也遵守 ,实现了协议方法,这些方法可以被子类继承

4)protocol声明的方法可以让任何类区实现 ,protocol就是协议

5)oc中不能继承多个类(单继承)但是能够遵守多个协议。继承( :)协议( < > )

6)基协议:<NSObject>是基协议,是最根本的协议,其中声明了很多方法。

7)协议可以遵守协议,一个协议遵守了另一个协议,就可以拥有另一个协议中的方法声明

4.protocol 中的@reuired 和@optional

@required和@optional 是协议方法声明中的两个关键字

他们主要控制方法是否要实现(默认的是@required) ,

用途 在于程序员之间的交流

@requried 表示必须要实现的方法

@optional 可以选择实现方法

5.protocol 类型限制

需要一女朋友的条件 定个协议

housHoldProtocl.h

@protocol houseHoldProtocol <NSObject>

- (void)zuoFan;

- (void)xiyifu;

@optional

-(void)job;

@end

1)使用id存储对象,对象的类型限制

格式 id<协议名称> 变量名

id <Myportocol> obj1;

//这样写后,表示是给人都满足条件

所以改为 id<houseHoldProtocol>girl ;

这样就行限制了 传进来的对象要遵守了协议才可以赋值

2)对象赋值类型限制

格式:类名<协议名>*变量名

Person<hoseHoldProtocol>*p

这样必须是人的类的对象才能赋值

3)对象的关联关系

要求人的狗会算数

@intterface Person:NSObject

//限制了这里传入的狗必须是遵守了dogProtocol的狗

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

@end

//狗遵守协议

@intreface Dog:NSObject <dogProtocol>

@end

id 和instancetype的区别

1)instancetyp只能作为函数或方法的返回值

2)id能作为方法或者函数的返回值、参数类型,也能用来定义一个变量

3)instancetype 对比id的好处: 能精确的的限制返回值的具体类型

6.protocol代理模式设计

实现 婴儿饿了要吃东西 ,困了要睡觉,

婴儿类 保姆类

#import <Foundation/Foundation.h>

@protocol baoMuProtocol <NSObject>
- (void)eatToBaby;

- (void)sleepToBaby;
@end
import <Foundation/Foundation.h>
#import "baoMuProtocol.h"
@class baby;
@interface baoMu : NSObject<baoMuProtocol>
@property (nonatomic,weak) baby *baby;
@end
#import "baoMu.h"
#import "baby.h"
@implementation baoMu
- (void)eatToBaby{
NSLog(@"保姆正在给baby喂奶");

}
- (void)sleepToBaby{
NSLog(@"保姆正在哄baby睡觉");
}
@end
#import <Foundation/Foundation.h>
@class baoMu;
#import "baoMuProtocol.h"
@interface baby : NSObject
@property (nonatomic,strong) baoMu<baoMuProtocol>*baomu;
- (void)babyWantEat;
- (void)babyWantsleep;

@end
#import "baby.h"
#import "baoMu.h"
@implementation baby
- (void)babyWantEat{
NSLog(@"baby在哭。。。。");
[self.baomu eatToBaby];

}
- (void)babyWantsleep{
NSLog(@"baby在哭。。。。");
[self.baomu sleepToBaby];
}
@end
#import <Foundation/Foundation.h>
#import "baby.h"
#import "baoMu.h"

int main(int argc, const char * argv[]) {
@autoreleasepool {
baoMu *baomu =[[baoMu alloc] init];

baby * ba =[[baby alloc] init];
ba.baomu = baomu;

[ba  babyWantEat];

}
return 0;
}


protocol代理设计模式概念

传入对象,代替当前类完成某个功能,称为代理模式。

利用协议实现代理模式的主要思路:

1)定义一个协议,里面声明代理需需要实现的方法列表。

2)创建一个代理类,遵守上面的代理协议

3)在需要代理的类中,定义一个对象类型为id且遵守代理协议的成员变量

4)在类中调用成员变量_delegate(代理的方法),调用代理的类方法

5)main.m或其他类文件中,为类的成员变量赋值

理解应用通过中介找房子

#import <Foundation/Foundation.h>

@protocol findHouseProtocol <NSObject>
- (void)findHouse;
@end
#import <Foundation/Foundation.h>
#import "findHouseProtocol.h"
@interface LinkHome : NSObject<findHouseProtocol>

@end
#import "LinkHome.h"
#import "findHouseProtocol.h"
@implementation LinkHome
- (void)findHouse{
NSLog(@"链家地产正在给学生找房子");
}
@end

#import <Foundation/Foundation.h>
#import "findHouseProtocol.h"
@interface Student : NSObject
@property (nonatomic ,strong) id<findHouseProtocol>delegate;

-(void)needHouse;
@end
#import "Student.h"
#import "LinkHome.h"
@implementation Student
-(void)needHouse{
NSLog(@"学生需要一个温暖的家");
[self.delegate findHouse];
}
@end

#import <Foundation/Foundation.h>
#import "Student.h"
#import "LinkHome.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
//代理类
LinkHome *li = [[LinkHome alloc] init];

Student*stu =[[Student alloc] init];
stu.delegate=li;
[stu needHouse];
//代理类 LinKhome
//代理对象 delegate
//协议内容 findHouseProtocol
//协议内容  findHouse
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: