------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ------
OC加强--第三天学习视频总结:
1. block的概念及使用:
1)block定义格式:
无参无返回值:void (^block 变量名)()=^( ){代码块的语句;};
例如:
有参无返回值:
void (^变量名)(参数的类型及个数)=^(形参列表){代码块语句;};
有参有返回值:
返回值类型 (^变量名)(参数的类型及个数)=^(形参列表){代码块语句;};
无参有返回值:返回值类型 (^block 变量名)()=^( ){代码块的语句;};
2. block的typedef:
1)格式为:typedef 返回值类型 (^ 新类型/别名)(参数类型列表);
2) 代码讲解实例:
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[]) {
@autoreleasepool {
// 定义一个block变量,并且赋值
void (^myBlock)() = ^{
NSLog(@"helloworld");
};
myBlock();
//定义一个别名
// 给 没有返回值 没有参数的block起一个别名
// Block 是一个类型,不在是一个单纯的变量了
typedef void (^Block)();
Block b1;
//block类型的变量
b1 =^{
NSLog(@"helloworld");
};
b1();
//定义有参数\有返回值的 block类型
//定义新的别名
//返回值是int 有两个 int类型的参数
typedef int (^NewType1)(int ,int );
NewType1 nt1 = ^(int a,int b){
return a+b;
};
//连续定义多个 NewType类型的变量
NewType1 n1,n2,n3;
n1 = ^(int x,int y){
return x>y?x:y;
};
int s = nt1(12,23);
NSLog(@"s = %d",s);
}
return 0;
}
3. block访问外部变量问题:
1)当定义block的时候,block会把外部变量以const的方式复制一份,存放到block所在的内存中,此时存入了堆区;
2)而且block内部不允许修改外部变量值,
void test(){
int m = 10;
NSLog(@"1:m = %d",m); //10
NSLog(@"2:m addr = %p",&m); //栈区
void (^myBlock)()=^{
m = 100; // 错误,m的值不能被修改
NSLog(@"5:m addr = %p",&m); //堆区
};
NSLog(@"4:m addr = %p",&m); //栈区
//使用
myBlock();
}
3)当外部变量前面加上__block 时,此时不再以const方式复制,此时可以修改变量的值。4)定义的全局变量,在block内部可以修改其值;
4. block 作为函数的返回值:
1)使用typedef 定义一个新的类型;
2)用新定义的的类型作为函数的返回值;
3) 定义block变量接收函数返回值;
4)调用block;
实例代码:
typedef void (^newType)();
//block类型作为函数的返回值
//2) 用新定义的类型作为函数的返回值
newType test(){
//定义block变量
newType w1 = ^{
NSLog(@"xxxxx");
NSLog(@"hello world");
};
return w1; //返回值block
}
int main(int argc, const char * argv[]) {
@autoreleasepool {
//定义block类型的变量
//3) 定义block变量接收 函数返回的结果
newType n1 = test();
//4) 执行block
n1();
}
return 0;
}
5. block使用技巧和注意事项:
1)block的助记符是inlineblock;
2) 我们在定义block变量的时候,形参类型及个数,这个位置处可以加上形参名称。
6. protocol的定义:
1 )- 什么是协议?一些方法的声明,一般写到一个.h的头文件中
方法有两种:1) 必须实现 2) 选择实现
2) - 协议的作用:供其他的类去遵守,如果一个类遵守了一个协议,就应该实现这个协议中定义的必须要实现的方法
3) - 如何定义一个协议:
@protocol xxx <NSObject> 默认情况下遵守 NSObject协议
@end
实现如下:
@protocol workProtocol <NSObject>
-(void)work;
@end
4) - 类遵守协议的格式:1) 遵守一个协议,先导入头文件 @interface 类名 :NSObject <xxx>@end
2) 遵守多个协议:@interface 类名 :NSObject <xxx,aaa,bbb> @end
如:
//结论: 当我们遵守了某个协议后,就相当于这个类有了协议中所有的方法的声明
@interface Person : NSObject<baseProtocol>
7.protocol 使用注意事项:
1) 一个协议,可以遵守其他的协议(协议之间可以有继承关系)。
2) 一个类可以遵守多个协议
3) 一个协议可以被多个类遵守
4)protocol 就一个用途,用来声明一大堆方法(但是不声明实例比变量),不能实现方法;
8.protocol 中的@required 和@optional 协议关键字用法;
1)@required 表示要实现的方法;
2) @optional 可选择实现的方法,可以实现,也可以不实现;
9. protocol 的类型限制:
1) 使用ID存储对象时,对象的类型限制;
如:id <myprotocol>obj1;
2) 对象赋值时的类型限制:格式为:类名<协议名称>*变量名
3) 对象关联关系下,对象的类型限制
如:
@autoreleasepool {
Dog *d = [Dog new];
Girl *mm = [Girl new];
NSString *str =@"";
//增加类型限制
// 第一种类型限制:给id类型增加限制
// id<houseHold> obj;
//增加<houseHold>以后,表示,obj只能赋值遵守了houseHold协议的对象
//id<houseHold> obj = d;
// 第二种类型限制:
//表示,obj2赋值的时候,必须是Girl对象,并其遵守了 houseHold协议.
Girl<houseHold> *obj2 = mm;
// 第三种类型限制
obj2.dog = d;
}
10.Id 和instancetype 的区别:
1)instancetype只能作为函数或者方法的返回值;
2)Id 能作为方法或者函数的返回值,参数类型,也能用来定义变量;
3)instancetype 对比Id的好处是:能精确的限制返回值的具体类型;
11.protocol代理模式引入:
代理模式概念:传入的对象代替完成了某个功能,称为代理模式;
代理模式的场合使用:(1)监听场合(2)通知场合(3) 有些事情自己不想处理,交给别人处理。