------<a href="http://www.itheima.com"target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流!
函数指针的回忆:
定义函数指针:
1、把函数的声明拷贝过来
2、把函数名换成(*函数指针变量名)
3、形参名可写可不写
int (*p)(int x,int y);//其中p是函数指针变量名
用法:p=sum;
p=jian;
调用:p(2,3);
(*p)(2,3);
函数指针别名:
typedef(*NewType)(int x,int y);//这里NewType是一个方法名,(类名)
NewType f1,f2,f3;//f1实际类型 Int(*f1)(int x,int y);
Block的typedef和函数指针别名基本一样
利用typedef定义block类型(和指向函数的指针很像)
格式:
typedef 返回值类型(^新别名)(参数类型列表);
Typedef int(^MyBlock)(int ,int);
以后就可以利用这种类型定义block变量了。
<span style="font-size:14px;">int main(){
@autoreleasepool{
// 定义一个block变量,并且赋值
void(^myBlock)(){
NSLog(@"hello world");
};
myBlock;
//定义一个别名
//给没有返回值没有参数的block起一个别名
//Block是一个类型,不在是一个单纯的变量
typedef void(^Block)();
Block=b1;
//block类型的变量
b1=^{
NSLog(@"hello world");
};
b1();
}
return 0;
}
</span>
block访问外部变量问题
<span style="font-size:14px;">int main(){
@autoreleasepool{
int m=10;
NSLog(@"m=%d,m");//10
//定义变量,并且赋值
void(^myBlock)()=^{
//可以访问m的值
NSLog(@"m=%d",m);
};
myBlock();
</span>
block内部不可以修改block“外部的变量”
非局部变量会以const变量被拷贝并存储到block中,也就是说block对其实只读的
如果尝试在block内部给变量赋值,会报错。
如果实在是有在block内部修改局部变量的值,那么在这个局部变量前加__block:
__block int m=10;
void (^myBlock)()=^{
m=100;
NSLog(@"m=%d",m);
};
myBlock();
block作为函数的返回值:
void (^block)();
定义新的block类型
使用typedef定义一个新的类型
typedef void(^newType)();
//block类型作为函数的返回值
用新定义的类型作为函数的返回值
<span style="font-size:14px;">newType test(){
//定义block变量
newType w1=^{
NSLog(@"xxxxx");
};
return w1; //返回值block
}</span>
<span style="font-size:14px;">int main(){
@autoreleasepool{
//定义block类型的变量
//定义block变量接收 函数返回的结果
newType ni=test();
// 执行block
n1();
}
}</span>
这样就能打印出XXX
block使用技巧及其注意
block助记符:inlineBlock
我们在定义block变量的时候,形参类型及个数 这个位置处可以加上形参名
//声明,参数是int (^block)(int x,int y)
void test(int (^block)(int x,int y)){
};
//main函数
test(^int(int x,int y){
return x+y;
});
protocol概念及基本使用
protocol(协议)的基本概念:
定义一些方法的声明,一般写到一个.h的头文件中
方法有两种:
1、必须实现
2、选择实现
协议作用:
供其他的类去遵守,如果一个类遵守了一个协议,就应该事先这个协议中定义的必须要实现的方法
protocol的使用流程:
定义协议---》在类中采纳指定的协议---》实现协议中的方法(注意方法有必须实现和选择实现两种)
定义协议:
@protocol协议名称<NSObject>//默认遵守NSObject
//方法声明列表
@end
注意:
协议默认采纳NSObject的协议
采纳协议:
类遵守协议 :
创建类的时候遵守某个或者某几个协议
@interface类名:父类<协议名称>
@end
某个协议也遵守某个或者某些协议,一个协议可以遵守其他多个协议
协议遵守协议
@protocol协议名称<其他协议名称>
@end
多个协议之间用逗号,隔开
@protocol协议名称<其它协议名称1,其它协议名称2>
@end
//基础协议
//eat run
//Person采纳这个协议
使用协议的流程
---》定义协议
---》让类遵守这个协议
---》实现协议中
baseProtocol.h
#import<Foundation/Foundation.h>
//定义一个协议
@peotocol baseProtocol<NSObject>
-(void)eat;
-(void)run;
@end
Person.h类
<span style="font-size:14px;">//准守协议的步骤
#import<Foundation\Foundation.h>
//导入头文件
#import"baseProtocol.h"
//遵守协议
//实现方法
//结论:当我们准守了某个协议后,就相当于这个类有了协议中所有的方法声明
@interface Person:NSObject<baseProtocol>
@end
</span>
Person.m类
<span style="font-size:14px;">#import "Person.h"
@implementation Person
-(void)eat{
NSLog(@"人会吃");
}
-(void)run{
NSLog(@"人会跑");
}
main.m
#import<Foundation\Foundation.h>
#import "Person.h"
int main(){
@autoreleasepool Person{
Person *p=[Person new];
[p run];
[p era];
}
return 0;
}
</span>
protocol的使用注意:
OC中的协议(protocol)使用注意:
1、就一个用途,用来声明一大推的方法(不能声明成员变量),不能实现
2只要某个类遵守了这个协议,就拥有了这个协议中的所有声明方法
3只要父类遵守了某个协议,那么子类也遵守
4、protocol声明的方法可以让任何类去实现,protocol就是协议
5、OC不能继承多个类,单是能够遵守多个协议。继承(:)遵守协议(<>)
6、基协议:<NSObject>是基协议,是最基本的协议,其中声明了很多最基本的方法
7、协议可以准守协议,一个协议准守了另一个协议,就可以拥有另一份协议中的方法声明
协议之间可以由继承关系
类如果采纳协议后,实现了协议的方法,这些方法可以被子类继承
protocol中@required和@option
@required表示必须要实现的方法
@option表示可以选择实现的方法
protocol类型限制
protocol代理设计模式概念:
传入的对象,代替当前类完成了某个功能,称为代理模式
利用协议实现代理模式的主要思路为:
定义一个协议,里面声明代理需要实现的方法列表,比如这里
学生找房子实例:
<span style="font-size:14px;">findHouseProtocol.h文件
#import<Foundation\Foundation.h>
@protocol findHousePortocol<NSObject>
-(void)findHouse;
@end
Student.h文件
#import<Foundation\Foundation.h>
#import "findHouseProtocol.h"
intface Student :NSObject
-(void)needHouse;
@property(nonatomic,strong)id<findHouseProtocol>delegate;
@end
Student.m文件
#import "Student.h"
@implementation Student
-(void)needHouse{
NSLog(@"学生需要一个温暖的房子");
[self.delegate findHouse]
}
@end
linkHouse.h文件
#import<Foundation\Foundation.h>
intface linkHouse:NSObject<findHouseProtocol>
@end
linkHouse.m文件
@implementation linkHouse
-(void)findHouse{
NSLog(@"正在帮学生找房子");
}
@end
main.m 文件
#import<Foundation\Foundation.h>
int main(){
@implementation{
Student *stu=[Student new];
//代理的类
LinkHouse *linkHouse=[LinkHouse new];
stu.delegate=linkHome;
[stu needHouse];
//代理类 LinkHouse
//代理对象 delegate
//协议 findHouseProtocol
//协议内容 findHouse
@end</span>
@protocol使用补充:
可以使用@protocol 协议名 引入这样就相当于@class引入
1、要遵守这个协议的类,用@protocol告诉编译器这是一个协议
2、在.m文件中,导入协议
3、在main函数中,也要导入协议头文件