
block的基本使用
1 // 有参有返回值
2 /*
3 格式:
4 返回值类型 (^变量名)(参数类型及个数) = ^(形参列表){
5
6 代码块语句;
7
8 return ;
9
10 };
11
12 */
13 // 定义一个有参数\有返回值的block
14 int (^myblock1)(int ,int) = ^(int x,int y){
15
16 return x+y;
17
18 };
19
20 int sum = myblock1(10,20);
21 NSLog(@"sum = %d",sum);
22
23 // 给变量重新赋值
24 myblock1 =^(int x,int y){
25
26 return x*y;
27
28 };
29
30 // 使用block,接收返回值
31 sum = myblock1(10,20);
32 NSLog(@"sum = %d",sum);
33
34 // 有参无返回值
35
36 /*
37 格式:
38 void (^变量名)(参数类型及个数) = ^(形参列表){
39
40 代码块语句;
41
42 };
43
44 */
45 // 定义一个变量myblock2 同时进行赋值
46 void (^myblock2)(int ,int )=^(int a,int b){
47
48 NSLog(@"a + b = %d",a+b);
49
50 };
51
52 myblock2(34,12);
53
54 // 先定义变量,再赋值
55 myblock2 = ^(int x,int y){
56
57 int m = x>y?x:y;
58 NSLog(@"max = %d",m);
59
60 };
61 myblock2(34,12);
62
63 // 无参无返回值 block
64
65 /*
66 //定义一个没有参数\没有返回值的block变量,并且赋值了
67 void (^block变量名)() = ^(){
68
69 代码块的语句;
70 };
71
72 优化:
73 void (^block变量名)() = ^{
74
75 代码块的语句;
76 };
77
78 //block变量的使用
79 block变量名();
80
81 */
82
83 void (^myBlock4)()=^{
84
85 NSLog(@"xxxx");
86 PRintf("xxxxxx");
87
88 };
89
90 //使用block变量
91 myBlock4();
block的typedef
typedef int (^myBlock)(int,int);
myBlock a = ^(int x, int y){
return x + y;
};
int c = a(1,2);
block访问外部变量
1 int main(int argc, const char * argv[]) {
2 @autoreleasepool {
3 int m = 10;
4
5 NSLog(@"1:m = %d",m); // 10
6 NSLog(@"2:m addr = %p",&m); // 栈区
7 // NSString *str = @"abc";
8 // NSLog(@"str = %p",str);
9
10 // 定义变量,并且赋值
11 // 当定义block的时候,block会把外部变量以const的方式复制一份
12 // 存放到block的所在的内存中
13 void (^myBlock)()=^{
14 // m的值不能被修改
15 // m = 100;
16
17 NSLog(@"5:m addr = %p",&m); // 堆区
18 // 可以访问m的值
19 NSLog(@"3:in block m = %d",m); // 10
20
21 };
22
23 NSLog(@"4:m addr = %p",&m); // 栈区
24 // 使用
25 myBlock();
26 }
27 return 0;
28 }
打印结果为

// 全局变量存在于数据段
int n=0;
int main(int argc, const char * argv[]) {
@autoreleasepool {
__block int m = 10;
NSLog(@"1:m add = %p",&m); // 栈区地址
NSLog(@"2:m = %d",m);
n = 10;
NSLog(@"7:n add = %p",&n); // 数据段
NSLog(@"8:n = %d",n); // 10
// 静态变量
static int a = 33;
NSLog(@"----------%p", &a); // 数据段
// __block 不在以const的方式拷贝
void (^myBlock)()=^{
int x = 100; // 栈区
// m的值可以被修改
m = 100;
// 全局变量可以修改
n = 100;
// 静态变量可以修改
a = 10;
NSLog(@"4:m addr = %p",&m); // 堆区
// 可以访问m的值
NSLog(@"3:in block m = %d",m); // 100
NSLog(@"9:n add = %p",&n); // 数据段
NSLog(@"10:n = %d",n); // 100
};
myBlock();
NSLog(@"5:m = %d",m); // 100
NSLog(@"6:m addr = %p",&m); // 堆区
NSLog(@"11:n add = %p",&n); // 数据段
NSLog(@"12:n = %d",n); // 100
}
return 0;
}
打印结果为

block使用注意
静态变量 和 全局变量 在加不加 __block都会直接引用变量地址。也就意味着 可以改变修改变量的值,在没有加__block参数的情况下
全局block:定义在函数外面的block是global(全体的)的 另外如果在函数内部的block,没有捕获任何自动变量,那么它也是全局的
栈block:区别为是否引用了外部变量
堆block:是对栈block copy得来。对全局block copy 不会有任何作用,返回的仍然是全局block
block作为函数的返回值
// 定义了一个新的类型 newType2
typedef int(^myBlock)(int ,int );
myBlock test(){
// 返回block类型
return ^(int a,int b){
return a+b;
};
}
int main() {
myBlock n = test();
int a = n(1,2);
NSLog(@"a = %d", a); // 3
}
block助记符 inlineblock
block 也可以这么定义
// 可以加上形参
int (^block)(int x,int y) = ^(int x, int y){
return x + y;
};
协议 Protocol
什么是协议?
一些方法的声明,一般写到一个.h的头文件中
方法有两种: 1) 必须实现 2) 选择实现
协议的作用:
供其他的类去遵守,如果一个类遵守了一个协议,就应该实现这个协议中定义的必须要实现的方法
协议的写法
@protocol xxxx <NSObject> // 必须实现的方法(默认) @required // 可选实现的方法 @optional @end
遵守协议的步骤: 1) 导入 头文件 2) 遵守协议 3) 实现方法
protocol类型限制
第一种类型限制:给id类型增加限制
id<xxxxxxx> obj;
增加<xxxxxxx>以后,表示,obj只能赋值遵守了xxxxxxx协议的对象
id<xxxxxxx> obj = d;
第二种类型限制:
表示,obj2赋值的时候,必须是Girl对象,并其遵守 了 xxxxxxx协议.
Girl *mm = [Girl new];
Girl<xxxxxxx> *obj2 = mm;
protocol代理设计模式
请看我之前的博客 >---请点击这里---<
------------------------------------------------------------------------------------------------------------------------------------------------------------
其他四篇链家如下:
Objective-C知识总结(1)
Objective-C知识总结(2)
Objective-C知识总结(3)
Objective-C知识总结(4)