黑马程序员--iOS--Objective-C基础 (内存管理三)

本文详细介绍了Block和Protocol在Objective-C中的概念、基本用法、分类及应用,包括Block的定义、使用、访问外部变量、分类、作为函数返回值,以及Protocol的定义、基本应用、使用注意事项等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

------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>


------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值