OC进阶(三)

1.block的基本使用

#import <Foundation/Foundation.h>

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        
        
        
        
        //1.无参数 无返回值
        
        void(^myBlock)() = ^
        {
        
            NSLog(@"block");
        
        };
        
        //2.有参无返回值
        
        void(^myBlock2)(int,int) = ^(int a,int y){

            NSLog(@"%d",a+y);
        
        };
        
        //3.有参数有返回值
        int(^myBlock3)(int,int) = ^(int a, int b){
        
        
            return a+b;
        
        };
        
        
        //block使用
        myBlock();
        myBlock2(12,14);
        int c =   myBlock3(10,100);
        NSLog(@"%d",c);
        
        
    }
    return 0;
}

2.block和typedef

#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访问外部的值

#import <Foundation/Foundation.h>
/**
 *  block内部访问外部值的问题
 *  block内部不允许修改外部变量值
 */
void test(){

    int m = 10;
    
    NSLog(@"1:m = %d",m);   //10
    NSLog(@"2:m addr = %p",&m);         //栈区
    //        NSString *str = @"abc";
    //        NSLog(@"str = %p",str);
    
    //定义变量,并且赋值
    //当定义block的时候,block会把外部变量以const的方式复制一份
    //存放到block的所在的内存中
    void (^myBlock)()=^{
        //m的值不能被修改
        //m = 100;
        
        NSLog(@"5:m addr = %p",&m);     //堆区
        //可以访问m的值
        NSLog(@"3:in block m = %d",m);  // ?
        
    };
    
    NSLog(@"4:m addr = %p",&m); //栈区
    //使用
    myBlock();
    
    
    // 1 2 4 5 3


}
//int n=0;
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        
        __block int m = 10;
        NSLog(@"1:m add  = %p",&m);   //栈区地址
 
        //__block 不在以const的方式拷贝
        void (^myBlock)()=^{
            //m的值不能被修改
            m = 100;
//            n = 10;
//            int m = 100;
            NSLog(@"5:m addr = %p",&m);     //堆区
            //可以访问m的值
            NSLog(@"3:in block m = %d",m);  // ?
        
        };
        myBlock();
        
        NSLog(@"6:m = %d",m);  // ?
        NSLog(@"7:m addr = %p",&m);

    }
    return 0;
}

4.block作为函数的返回值

#import <Foundation/Foundation.h>
//返回值是block类型的
//void (^block)();
//定义新的block类型
//1) 使用 typedef 定义一个新的类型
typedef void (^newType)();

//block类型作为函数的返回值
//2) 用新定义的类型作为函数的返回值
newType test(){
    //定义block变量
    newType w1 = ^{
    
        NSLog(@"xxxxx");
        NSLog(@"hello world");
    };

    return w1;  //返回值block

}

//重新定义了一个新的类型 newType2
typedef int(^newType2)(int ,int );
newType2 test2(){

    //返回一个特殊的"值" 这个值是一个有返回值,有两个参数的的代码块
    return ^(int a,int b){

        return  a+b;
    };

}


int main(int argc, const char * argv[]) {
    @autoreleasepool {
        
        //定义block类型的变量
        //3) 定义block变量接收 函数返回的结果
        newType n1 = test();
        //4) 执行block
        n1();
        /*
         n2 =^(int a,int b){
         
         return  a+b;
         };
         
         
         */
        newType2 n2 = test2();
        //调用block
        int s =  n2(23,12);
        NSLog(@"s = %d",s);
        
    }
    return 0;
}

5.block作为方法的参数

#import "Person.h"

@implementation Person
-(void)test:(BlockType) block{

    if (block !=nil) {
        
        block();
        
    }
    
 
    

}
@end
#import <Foundation/Foundation.h>
#import "Person.h"
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        
        Person *p = [Person new];
        [p test:^{
            NSLog(@"xxxxx");
        }];
        
    }
    return 0;
}

6.协议

/*
     1 - 什么是协议?
 
       一些方法的声明,一般写到一个.h的头文件中
       方法有两种:
 
       1) 必须实现
       2) 选择实现
 
     2 - 协议的作用:
 
       供其他的类去遵守,
       如果一个类遵守了一个协议,就应该实现这个协议中定义的必须要实现的方法
 
     3 - 如何定义一个协议:
 
       @protocol xxx <NSObject>  默认情况下遵守 NSObject协议
 
       @end
 
     4 - 类遵守协议的格式:

       1) 遵守一个协议:
 
         先导入头文件
 
       @interface 类名 :NSObject <xxx>
 
       @end
 
       2) 遵守多个协议 
         @interface 类名 :NSObject <xxx,aaa,bbb>
         
         @end
 
 
 */

7.@required @optional 

@protocol baseProtocol <NSObject>
//@required 和 @optional 都是协议中的关键字
//@required 修饰的方法是必须要实现的
@required    //默认情况下都是必须要实现的
-(void)run;
-(void)eat;

//@optional 修饰的方法是可以实现,也可以不实现的
@optional
-(void)dajia;

@end

8.protocol的类型限制

int main(int argc, const char * argv[]) {
    @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;
        
    }
    return 0;
}
@interface Girl : NSObject<houseHold>

//女孩养一条狗,
//要求这个狗,必须会算数
@property (nonatomic,strong) Dog<caculatorProtocol> *dog;
@end

9.代理模式

#import <Foundation/Foundation.h>
@class Baby;
@protocol lookBabyProtocol <NSObject>
//喂婴儿吃饭
-(void)feedBabyEat:(Baby *)baby;
//哄婴儿睡觉:(Baby *)baby
-(void)HongBabySleep:(Baby *)baby;

@end
#import <Foundation/Foundation.h>
@class BaoMu;
#import "lookBabyProtocol.h"
@interface Baby : NSObject
@property (nonatomic,assign) float blood;
@property (nonatomic,assign) float sleep;
//保姆、体力值、睡眠值
@property (nonatomic,strong) BaoMu<lookBabyProtocol> *bm;
-(void)wantEat;
-(void)wantSleep;
@end
#import "Baby.h"
#import "BaoMu.h"

@implementation Baby
-(void)wantEat{

    NSLog(@"婴儿在哭...");
    //保姆要喂它吃
    [self.bm feedBabyEat:self];

}
-(void)wantSleep{

    NSLog(@"婴儿在哭...");
    //保姆哄婴儿睡觉
    [self.bm HongBabySleep:self];
}
@end
#import <Foundation/Foundation.h>
//保姆想成为baby的代理人,就必须遵守lookBabyProtocol协议
#import "lookBabyProtocol.h"

@interface BaoMu : NSObject<lookBabyProtocol>

@end
@implementation BaoMu
//喂婴儿吃饭
-(void)feedBabyEat:(Baby *)baby{
    baby.blood += 20;
    NSLog(@"保姆正在喂婴儿吃东西,baby.blood = %.2f",baby.blood);
}
//哄婴儿睡觉
-(void)HongBabySleep:(Baby *)baby{

    baby.sleep += 10;
    NSLog(@"保姆正在哄婴儿睡觉,baby.sleep = %.2f",baby.sleep);

}
@end

 

posted @ 2015-10-28 16:14  ios开发那点事  阅读(317)  评论(0编辑  收藏  举报