ios nslog 例子_iOS Block实例

iOS之Block详解:Block详解

ViewController.h(ARC)

#import

@interface ViewController : UIViewController

// 属性声明的block都是全局的__NSGlobalBlock__

@property (nonatomic, copy) void (^copyBlock)();

@property (nonatomic, weak) void (^weakBlock)();

@end

ViewController.m(ARC)

#import "ViewController.h"

#import "Test.h"

typedef void (^blockSave)(void);

typedef void (^typedefBlock)(void);

void (^outFuncBlock)(void) = ^{

NSLog(@"someBlock");

};

@implementation ViewController

- (void)viewDidLoad {

[super viewDidLoad];

NSLog(@"block : %@", ^{NSLog(@"block");}); // __NSGlobalBlock__

NSString *str3 = @"1234";

NSLog(@"block is %@", ^{NSLog(@":%@", str3);}); // __NSStackBlock__

#pragma mark - 当全局block引用了外部变量,ARC机制优化会将Global的block,转为Malloc(堆)的block进行调用。

__block int age = 20;

int *ptr = &age;

// ARC下

blockSave x = ^{

NSLog(@"(++age):%d", ++age); // 变量前不加__block的情况下,会报错,变量的值只能获取,不能更改

};

blockSave y = [x copy];

y();

NSLog(@"x():%@, y():%@ , (*ptr):%d", x, y, *ptr);

// MRC下

Test *test = [[Test alloc] init];

[test test];

[test exampleB];

/**总结:

ARC下:(++age):21 (*ptr):20 // blockSave在堆中,*ptr在栈中

MRC下:(++age):21 (*ptr):21 // blockSave和*ptr都在栈中

*/

#pragma mark - copyBlock(未使用函数内变量) __NSGlobalBlock__

self.copyBlock = ^{

};

NSLog(@"1:%@", self.copyBlock);

#pragma mark - weakBlock(未使用函数内变量) __NSGlobalBlock__

self.weakBlock = ^{

};

NSLog(@"2:%@", self.weakBlock);

#pragma mark - copyBlock (使用函数内变量) __NSMallocBlock__

self.copyBlock = ^{

age = age+1-1;

};

NSLog(@"3:%@", self.copyBlock);

#pragma mark - weakBlock(使用函数内变量) __NSStackBlock__

self.weakBlock = ^{

age = age+1-1;

};

NSLog(@"4:%@", self.weakBlock);

#pragma mark - someBlock(定义在函数体外) __NSGlobalBlock__

NSLog(@"5:%@", outFuncBlock);

#pragma mark - typedefBlock(函数体外自定义的Block) __NSGlobalBlock__

typedefBlock b = ^{

};

NSLog(@"6:%@", b);

#pragma mark - 对栈中的block进行copy

// 不引用外部变量,定义在全局区、表达式没有使用到外部变量时,生成的block都是__NSGlobalBlock__类型

void (^testBlock1)() = ^(){

};

NSLog(@"testBlock1: %@", testBlock1);

// 引用外部变量 -- ARC下默认对block进行了copy操作,所以这里是__NSMallocBlock__类型

void (^testBlock2)() = ^(){

age = age+1-1;

};

NSLog(@"testBlock2: %@", testBlock2);

// Blocks提供了将Block和__block变量从栈上复制到堆上的方法来解决变量作用域结束时销毁的问题,堆上的Block会依然存在。

/*那么什么时候栈上的Block会复制到堆上呢?

1.调用Block的copy实例方法时

2.Block作为函数返回值返回时(作为参数则不会)

3.将Block赋值给附有__strong修饰符id类型的类或Block类型成员变量时

4.将方法名中含有usingBlock的Cocoa框架方法或GCD的API中传递Block时

在使用__block变量的Block从栈上复制到堆上时,__block变量也被从栈复制到堆上并被Block所持有。

*/

/*block里面使用self会造成循环引用吗?

1.很显然答案不都是,有些情况下是可以直接使用self的,比如调用系统的方法:

[UIView animateWithDuration:0.5 animations:^{

NSLog(@"%@", self);

}];

因为这个block存在于静态方法中,虽然block对self强引用着,但是self却不持有这个静态方法,所以完全可以在block内部使用self。

2.当block不是self的属性时,self并不持有这个block,所以也不存在循环引用

void(^block)(void) = ^() {

NSLog(@"%@", self);

};

block();

3.大部分GCD方法:

dispatch_async(dispatch_get_main_queue(), ^{

[self doSomething];

});

因为self并没有对GCD的block进行持有,没有形成循环引用。

4.……

只要我们抓住循环引用的本质,就不难理解这些东西。

*/

}

Test类在MRC条件下运行( -fno-objc-arc )

Test.h(MRC)

#import

@interface Test : NSObject

- (void)test;

@end

Test.m(MRC)

#import "Test.h"

@implementation Test

- (void)test

{

__block int age = 20;

int *ptr = &age;

void (^textBlock)() = ^{

NSLog(@"(++age):%d", ++age);

};

textBlock();

// 对block进行retain、release、copy,retainCount都不会变化,都为1

// [textBlock retain];

// [textBlock copy];

// [textBlock release];

NSLog(@"Test: textBlock:%@, (*ptr):%d, %lu", textBlock, *ptr, (unsigned long)[textBlock retainCount]);

/**

MRC下:(++age):21 (*ptr):21

*/

#pragma mark - 对栈中的block进行copy

// 不引用外部变量

/* 这里打印的是__NSGlobalBlock__类型,但是通过clang改写的底层代码指向的是栈区:impl.isa = &_NSConcreteStackBlock

这里引用巧神的一段话:由于 clang 改写的具体实现方式和 LLVM 不太一样,并且这里没有开启 ARC。所以这里我们看到 isa 指向的还是__NSStackBlock__。但在 LLVM 的实现中,开启 ARC 时,block 应该是 __NSGlobalBlock__ 类型

*/

void (^testBlock1)() = ^(){

};

void (^testBlock2)() = [testBlock1 copy];

NSLog(@"Test: testBlock1: %@, testBlock2: %@", testBlock1, testBlock2);

[testBlock2 release];

// 引用外部变量,block为__NSStackBlock__类型

void (^testBlock3)() = ^(){

age = age+1-1;

};

void (^testBlock4)() = [testBlock3 copy];

NSLog(@"Test: testBlock3: %@, testBlock4: %@", testBlock3, testBlock4);

[testBlock4 release];

}

github地址:BlockTest

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/332914.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

boot gwt_带Spring Boot的GWT

boot gwt介绍 我最近一直在研究用Java编写UI代码的选项。 在我以前的文章中,我研究了Eclipse RAP,发现它可以与Spring Boot集成在一个可执行jar中。 这次,我想对GWT做同样的技巧。 每个人都喜欢Spring Boot。 它使很多事情变得更加干净和容易…

工作占用了太多私人时间_下班后还要被逼谈工作,我们应该如何处理?

老板总是下班后在跟我说工作的事情。不理吧,怕领导不高兴,回复了又怕没完没了的占用了自己的私人时间去完成工作,并且以后老板会觉得这样是理所当然,会变本加厉。“幻想花开”是一家装修公司的设计师,公司里的业务量越…

oh-my-zsh中如何去掉命令提示符前缀

终端的提示符前面存在着一长串前缀:用户名主机名,有时候命令稍微长点,一整行就放不下,于是找到了消除前缀的办法: 输入快捷键 Shift Command G,在前往文件夹输入框中输入 ~/.oh-my-zsh/themes/&#xff…

迁移学习 简而言之_简而言之SPIFFE

迁移学习 简而言之我一直在研究SPIFEE(每个人的安全生产身份框架)[1],在这里,我正在按照我现在的理解起草流程,以使任何其他试图了解流程的人受益。 身份注册表 – SPIRE服务器具有自己的身份注册表,该注册…

MyBatisPlus使用教程

lt是小于 gt是大于

cap理论具体含义_架构设计之「 CAP 定理 」

在计算机领域,如果是初入行就算了,如果是多年的老码农还不懂 CAP 定理,那就真的说不过去了。CAP可是每一名技术架构师都必须掌握的基础原则啊。现在只要是稍微大一点的互联网项目都是采用 分布式 结构了,一个系统可能有多个节点组…

用于zsh的高亮插件 zsh-syntax-highlighting

文章目录简介安装配置简介 zsh-syntax-highlighting 插件为 shell zsh 提供语法高亮显示。当命令在 zsh 提示符下输入到交互式终端时,它可以突出显示命令。这有助于在运行命令之前检查命令,特别是捕获语法错误。 主页地址:https://github.c…

项目不能使用fn标签_无服务器,Java和FN项目的第一步

项目不能使用fn标签无服务器不是什么新事物,但是可以说,仍然有很多关于它的炒作,以及它将如何改变一切,以及未来将如何成为无服务器。 除了云提供商提供的无服务器/功能之外,还有越来越多的无服务器项目正在我们的路上…

tomcat目录下创建临时文件,长时间没有使用会被系统清理掉

原因 原因:在linux系统中,spring boot应用服务每次使用java -jar启动后都会在/tmp目录下生成如下目录: hsperfdata_root tomcat.***.9008(中间是一串数字,结尾是应用端口号) tomcat-docbase..9008&#x…

iTerm2的颜色主题/配色主题/配色方案

文章目录直接下载配色方案包使用命令下载安装配色方案直接下载配色方案包 GitHub 主页地址:https://github.com/mbadolato/iTerm2-Color-Schemes 颜色方案下载地址:https://iterm2colorschemes.com/ 下载压缩包后对其进行解压缩,打开目录找…

android 技能标签功能_iOS和Android用户体验设计差异

摘要:iOS和Android用户体验设计差异关键词:iOS,Android,用户体验设计本文将讨论iOS和Android之间的具体设计差异。基本差异1、设计规范 iOS和Android遵循不同的设计规范。2、度量单位 iOS应用程序设计是在pt中开发的,而…

java线程池返回线程状态_Java线程的不同状态

java线程池返回线程状态介绍 在Java中,线程可以具有状态。 Thread.State枚举定义Java线程可以具有的不同状态。 该枚举定义了以下值– 新 可运行 已封锁 等候 TIMED_WAITING 已终止 在随后的部分中,我将简要概述这些状态以及它们之间的可能过渡。…

远程Linux主机安装Oh My Zsh

文章目录介绍安装安装后介绍 Oh My Zsh is an open source, community-driven framework for managing your Zsh configuration. 安装 如果你的服务器没有安装 zsh,则要先安装 zsh: yum install zsh要先安装 git: yum install git然后安…

处理Nginx返回octet-stream数据流的配置

解决 修改Nginx的配置将add_header Content-length 0;删除,处理 Content-Type为application/octet-stream 一、请求报文 二、异常信息 对应前端页面的异常信息为: Network Error epoll_wait() reported that client prematurely closed c…

multi task训练torch_Multi-task Learning的三个小知识

本文译自Deep Multi-Task Learning – 3 Lessons Learned by Zohar Komarovsky在过去几年里,Multi-Task Learning (MTL)广泛用于解决多个Taboola(公司名)的业务问题。在这些业务问题中, 人们使用一组相同的特征以及深度学习模型来…

java8多线程运行程序_线程,代码和数据–多线程Java程序实际运行的方式

java8多线程运行程序有些事情是您在学术或培训班上没有学到的,经过几年的工作经验后才逐渐了解,然后才意识到,这是非常基本的事情,我为什么错过了这么多年。 了解多线程Java程序的执行方式就是其中之一。 您肯定已经听说过线程&am…

zsh命令行界面/zsh终端界面粘贴卡顿的问题

因为安装了某些zsh插件导致,在zsh命令行中粘贴文本非常卡顿,解决方案就是把下面的代码复制到 ~/.zshrc 文件中: pasteinit() {OLD_SELF_INSERT${${(s.:.)widgets[self-insert]}[2,3]}zle -N self-insert url-quote-magic # I wonder if youd…

java连接mongodb的jar包_Java实战之管家婆记账系统(1)——项目简述

项目简述:该项目是一个通过JavaFX实现的管家婆记账系统,具有记账的功能。使用软件:IntelliJ IDEA 2018.3.5(Ultim ate Edition):编写Java项目代码。JavaFX Scene Builder 2.0:生成fxml界面文件。Navicat for MySQL&…

oauth2.0协议流程_正确的工作流程:我应该使用哪个OAuth 2.0流程?

oauth2.0协议流程什么是OAuth 2.0 OAuth 2.0是一个已被广泛采用的委托授权框架,已经存在了很多年,并且似乎已经存在。 如果您不熟悉OAuth 2.0的基本概念,可以使用 川崎孝彦写的优秀文章 。 这只是OAuth 2.0各方的简要提醒: 资源…

远程Linux主机安装zsh插件zsh-syntax-highlighting

安装说明: https://github.com/zsh-users/zsh-syntax-highlighting/blob/master/INSTALL.md 根据安装说明: 1.Clone this repository in oh-my-zsh’s plugins directory: git clone https://github.com/zsh-users/zsh-syntax-highlightin…