------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; }