------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
Block 的概念和基本用法
Block 类型是一个C级别的语法和运行机制。它除了拥有可执行代码外,还包含了与堆、栈内存绑定的变量。
可以用Block来写可以传到API中的函数语句,可选择性的存储,可以使用多线程。
block的基本用法
<span style="font-size:12px;">//
//无参无返回值
/*
//定义了一个无参无返回值的block变量,并且赋值
void (^ 变量名)() = ^(){
代码块语句;
};
//block变量的使用
block变量名 ();
*/
//有参无返回值
/*
//定义了一个无参无返回值的block变量,并且赋值
void (^ 变量名)(参数类型及个数) = ^(形参列表){
代码块语句;
};
*/
//有参有返回值
/*
//定义了一个无参无返回值的block变量,并且赋值
返回子类型 (^变量名)(参数类型及个数) = ^(形参列表){
代码块语句;
return ;
};
*/
//有参无返回值
/*
//定义了一个无参无返回值的block变量,并且赋值
void (^变量名)(参数类型及个数) = ^(形参列表){
代码块语句;
};
*/
void (^myblock)(int ,int ) = ^(int a,int b){
NSLog(@"a+b = %d",a+b);
};
int (^myblock1)(int ,int ) = ^(int x,int y){
return x+y;
};
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[]) {
@autoreleasepool {
myblock(13,67);
int sum = myblock1(67,89);
NSLog(@"sum = %d",sum);
}
return 0;
}
</span>
2、block 的typedef
格式:
typedef 返回值类型 (^新别名)(参数类型列表);
<span style="font-size:12px;">#import <Foundation/Foundation.h>
int main(int argc, const char * argv[]) {
@autoreleasepool {
//给一个有参数有返回值的block类型 起了个别名 为newtype
typedef int (^newtype) (int ,int );
newtype aa = ^(int a,int b){
return a+b;
};
int sum = aa(45,88);
NSLog(@"sum = %d",sum);
}
return 0;
}</span>
block访问外部变量
首先它是可以访问外部变量的值的,但是这两个变量的地址是不一样的。
因为在当定义一个block的时候,block会把外部变量以 const 的方式复制一份存放在block所在的内存中。所以这个外部变量的值是不可以修改的。
__block int n = 1;则可以修改外部变量的值,不以const方式拷贝。但是地址还是会改变。
block的分类
全局block: 定义在函数外面的block是全局的;另外函数内部的block没有捕获任何自动变量,那么也是全局的
栈block : 是否引用了外部变量
堆block ;是对栈block copy的来的
block作为函数的返回值
<span style="font-size:12px;">#import <Foundation/Foundation.h>
typedef int (^newtype)(int,int );//定义一个新的类型作为函数的返回值
newtype test(){
newtype n1 = ^(int a,int b){
return a+b;//返回值block
};
return n1;//返回值block
}
int main(int argc, const char * argv[]) {
@autoreleasepool {
newtype n2 = test();//定义变量接受函数返回值
int sum = n2(78,56);//调用block
NSLog(@"sum = %d",sum);
}
return 0;
}</span>
protocol概念和基本应用
在OC中,接口的是由协议的 protocol来实现的,可以用来声明一些必须要实现的方法和选择实现的方法。
使用流程:
定义协议 .h文件中 ----------->采用协议 classA.h 中类声明的时候采纳协议 ------------>classA.m 中实现协议对应的方法
格式:
@protocol 协议名称 <NSObject> //默认遵守NSObject 协议
//声明方法列表
@end
@interface 类名 :基类 <协议名称>
@end
某个协议可以遵守其他协议,也可以遵守多个协议,用逗号隔开就可以了。
<span style="font-size:12px;">#import <Foundation/Foundation.h>
@protocol Animalprotocol <NSObject>
-(void)run;
@end</span>
<span style="font-size:12px;">#import <Foundation/Foundation.h>
#import "Animalprotocol.h"
@interface Person : NSObject<Animalprotocol>
@end</span>
protocol 使用注意事项:
1)只要遵守了这个协议,就拥有了这个协议所有的方法声明。
2)OC不能多继承,但是可以遵守多个协议
3)protocol 用来声明一大堆方法(不能声明成员变量),不能写实现。
protocol中的两个关键字: @required @optional
主要是来控制方法是否需要实现
@required 这个方法必须要实现 @optional 这个方法不一定要实现
<span style="font-size:12px;">#import <Foundation/Foundation.h>
@protocol baseprotocol <NSObject>
@required
-(void)eat;
@optional
-(void)fight;
@end</span>
protocol代理设计模式
概念:传入的对象,代替当前类实现某个功能
思路:
1)定义一个协议,里面声明需要代理去实现的方法列表
<span style="font-size:12px;">#import <Foundation/Foundation.h>
@protocol findHouse <NSObject>
-(void)findHouse;
@end
</span>
2)代理需要遵守指定的协议<span style="font-size:12px;">#import <Foundation/Foundation.h>
#import "findHouse.h"
@interface linkHome : NSObject<findHouse>
@end</span>
3)在被代理的类中,定义一个对象类型为id并且遵守代理协议的成员变量
<span style="font-size:12px;">#import <Foundation/Foundation.h>
#import "findHouse.h"
@interface Student : NSObject
-(void)needHouse;
@property (nonatomic ,strong) id<findHouse> delegate;
@end</span>
4)在被代理类中调用成员变量 _delegate 的方法,调用代理方法
<span style="font-size:12px;">#import "Student.h"
@implementation Student
-(void)needHouse{
NSLog(@"need house");
[self.delegate findHouse];
}
@end</span>
5)main.m中为被代理类的成员变量赋值
<span style="font-size:12px;">#import <Foundation/Foundation.h>
#import "Student.h"
#import "linkHome.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
Student *student = [Student new];
linkHome *linkhome = [linkHome new];
student.delegate =linkhome;
[student needHouse];
}
return 0;
}</span>