OC 中的block存储位置

一、block块的存储位置(block块入口地址):可能存放在2个地方:代码区、堆区(程序分5个区,还有常量区、全局区和栈区)。

详细介绍:

情况1:代码区

不访问处于栈区的变量(例如局部变量),且不访问处于堆区的变量(例如alloc创建的对象)。也就是说访问全局变量也可以。

/**
  没有访问任何变量
 */
int main(int argc, char * argv[]) {
    void (^block)(void) = ^{
        NSLog(@"===");
    };
    block();
}
/**
  访问了全局(静态)变量
 */
int  iVar = 10;
int main(int argc, char * argv[]) {
    void (^block)(void) = ^{
        NSLog(@"===%d",iVar);
    };
    block();
}

情况2:堆区

如果访问了处于栈区的变量(例如局部变量),或处于堆区的变量(例如alloc创建的对象)。都会存放在堆区

/**
  访问局部变量
 */
int main(int argc, char * argv[]) {
    int iVar = 10;
    void (^block)(void) = ^{
        NSLog(@"===%d",iVar);
    };
    block();
}

二、代码存放在堆区时,就需要特别注意,因为堆区不像代码区不变化,堆区是不断变化的(不断创建销毁)。因此代码有可能会被销毁(当没有强指针指向时),如果这时再访问此段代码则会程序崩溃。因此,对于这种情况,我们在定义一个block属性时应指定为strong,或copy:

@property (nonatomic, strong) void (^myBlock)(void); // 这样就有强指针指向它

@property (nonatomic, copy)  void (^myBlock)(void);  // 并不会在堆区copy一份,原因见 三

而对于第一种情况,使用strong,copy(不会复制一份到堆区)也可以。因此定义block时最好指定为strong(推荐)或copy。

三、关于copy

copy:

1 copy可变变量:在赋值指针的同时也会复制指针指向的内存区域。深拷贝

2 copy不可变变量:等同于strong,还是浅拷贝

因为block是一段代码,即不可变的,所以并不会深拷贝

时间: 2024-10-25 03:16:12

OC 中的block存储位置的相关文章

oc中的block

#import <Foundation/Foundation.h> int main(int argc, const char * argv[]) { @autoreleasepool { //block的规则 //返回值类型(^block名称)(形参参数列表)一般形参变量名不用写= ^返回值类型(实参数列表){block体}; // int (^block3)(int) = ^(int)(int x){ return 101;}; //int result=block(3);调用 //注意要

java中变量的存储位置

1.寄存器:最快的存储区, 由编译器根据需求进行分配,我们在程序中无法控制. 2. 栈:存放基本类型的变量数据和对象的引用,但对象本身不存放在栈中,而是存放在堆(new 出来的对象)或者常量池中(字符串常量对象存放在常量池中.) 3. 堆:存放所有new出来的对象. 4. 静态域:存放静态成员(static定义的) 5. 常量池:存放字符串常量和基本类型常量(public static final). 6. 非RAM存储:硬盘等永久存储空间 这里我们主要关心栈,堆和常量池,对于栈和常量池中的对象

OC中的Block数据类型和protocol

Block数据类型 作用:封装一段代码,可以再任何地方执行. 定义格式:返回值类型 (^变量名)(传入的形参的数据类型) = ^(传入代码块的参数){代码块}; 调用方法:变量名(实参): block其实与函数差不多,他们的相同之处有: 1.都可以保存代码 2.都可以有返回值 3.都有形参和实参 4.调用方式一样 使用注意: 1.Block内部可以访问外面的成员变量 2.默认情况下,Block内部不能修改外面的局部变量 3.如果一定要在Block内部修改外面的局部变量,可以再该局部变量前加__b

OC 中的block使用

在iOS的开发过程中,使用块的地方很多也很方便,但是在使用块的过程中要注意内存泄露的问题. 在块创建的时候,会对块内的所有对象的引用计数加一,直到块销毁,所以在使用块的过程中需要我们进行处理,在这里以AFNetworking的代码举例,代码如下: __weak __typeof(self)weakSelf = self; self.backgroundTaskIdentifier = [application beginBackgroundTaskWithExpirationHandler:^{

oc中的block使用心得

typedef void (^ simpleBlock) (void); typedef double (^multiplyTwoValues)(double, double); typedef void (^ simpleTestBlock) (int ,int); @implementation TJAppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDic

关于OC中的block自己的一些理解(二)

一.block延伸:页面间反向传值 1)first页面的代码 - (void)viewDidLoad { [super viewDidLoad]; [self setupBtn]; self.view.backgroundColor = [UIColor whiteColor]; } - (void)setupBtn { UIButton * btn = [[UIButton alloc]init]; [btn addTarget:self action:@selector(buttonClic

iOS oc中的 block使用

int (^myBlock)(NSString *) = ^(NSString *string){ return [string intValue]; } ; int count = 0; int  块的类型   ^声明一个myBlock块 (NSString)有一个参数确定参数类型 ^(NSString *string){ return [string intValue]:}块对象的语法结构 也就是赋给myBlock的值 string参数名 {return [string intValue]}

Block存储域

第一.在OC中允许block改写值的变量有三种: 静态变量 全局变量 静态全局变量 code示例如下所示: int global_val=1; staticint static_global_val=2; int main(int argc,const char * argv[]) { @autoreleasepool { static int static_val=3; void (^blk)(void)=^{ global_val *=2; static_global_val+=3; sta

java数据的5种存储位置(转)

任何语言所编写的程序,其中的各类型的数据都需要一个存储位置,java中书的存储位置分为以下5种: 1.寄存器 最快的存储区,位于处理器内部,但是数量及其有限.所以寄存器根据需求自动分配,无序人为控制. 2.栈内存 位于RAM中,通过堆栈指针可以从处理器中获得直接支持.堆栈指针向下移动,则分配新的内存:向上移动,则释放哪些内存.这种存储方式仅次于寄存器.(常用于存放对象引用和基本数据类型,而不用于存储对象) 3.堆 一种通用的内存池,也位于RAM中.其中存放的数据由JVM自动进行管理. 堆相对于栈