Objective-C知识总结(5)

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)

posted @ 2015-07-28 22:29  Melody_Zhy  阅读(411)  评论(0编辑  收藏  举报