背景:

今天聊代码规范的问题的时候说了一下尾调用的问题。

一:概念:

什么是尾调用?

尾调用(Tail Call):某个函数的最后一步仅仅只是调用了一个函数(可以是自身,可以是另一个函数)。

注意 “仅仅” 两个字。

例子:

// 尾调用:
- (NSInteger)funcA:(NSInteger)num { /* Some codes... */ if (num == 0) {
return [self funcA:num];// 尾调用->自身
} if (num > 0) {
return [self funcB:num];// 尾调用->函数funcB
} return [self funcC:num];// 尾调用->函数funcC
}
// 不是尾调用1:
- (NSInteger)funcA:(NSInteger)num { NSInteger num = [self funcB:(num)]; return num;// 不是尾调用->最后一步是返回一个值,而不是调用一个函数
}
// 不是尾调用2:
- (NSInteger)funcA:(NSInteger)num { return [self funcB:(num)] + 1;// 不是尾调用->原因:最后一步不仅调用了函数还有 +1 操作
}

二:优化点(尾调用优化在Release模式下才会有,Debug模式下没有。)

例子:一直开辟新的栈空间(最后会栈溢出,最终导致崩溃。空间复杂度O(n),时间复杂度O(n)。)

例子:尾调用的优化可以重复利用栈空间(重用栈帧,不申请栈空间。
空间复杂度O(1),时间复杂度O(n)。)

三、总结

总结:
1. 尾调用:某个函数的最后一步仅仅调用了一个函数(可以是自身,可以是另一个函数)。
2. OC的尾调用优化的本质是:栈帧的复用
3. 尾调用优化实现原理:当函数A的最后一步仅仅是调用另一个函数B时(或者调用自身函数A),这时,因为函数A的位置信息和内部变量已经不会再用到了,直接把函数A的栈帧交给函数B使用。

四:附加思考:

 

思考:尾调用尾部加0可以达到尾调用优化,加.0就不能达到,是为什么呢?

注:

参考:https://www.jianshu.com/p/9e3cd9b1095a

iOS 的尾调用优化原理的更多相关文章

  1. ES6躬行记(15)——箭头函数和尾调用优化

    一.箭头函数 箭头函数(Arrow Function)是ES6提供的一个很实用的新功能,与普通函数相比,不但在语法上更为简洁,而且在使用时也有更多注意点,下面列出了其中的三点: (1)由于不能作为构造 ...

  2. JavaScript中的尾调用优化

    文章来源自:http://www.zhufengpeixun.com/qianduanjishuziliao/javaScriptzhuanti/2017-08-08/768.html JavaScr ...

  3. 前端项目中常用es6知识总结 -- 箭头函数及this指向、尾调用优化

    项目开发中一些常用的es6知识,主要是为以后分享小程序开发.node+koa项目开发以及vueSSR(vue服务端渲染)做个前置铺垫. 项目开发常用es6介绍 1.块级作用域 let const 2. ...

  4. js 调用栈机制与ES6尾调用优化介绍

    调用栈的英文名叫做Call Stack,大家或多或少是有听过的,但是对于js调用栈的工作方式以及如何在工作中利用这一特性,大部分人可能没有进行过更深入的研究,这块内容可以说对我们前端来说就是所谓的基础 ...

  5. ES6学习笔记 -- 尾调用优化

    什么是尾调用? 尾调用(Tail Call)是函数式编程的一个重要概念,就是指某个函数的最后一步是调用另一个函数. function f(x) { return g(x) } 如上,函数 f 的最后一 ...

  6. JS的递归与TCO尾调用优化

    转自:https://segmentfault.com/a/1190000004018047 这两天搜了下JS递归的相关文章, 觉得这篇文章很不错, 就顺手翻译了下,也算给自己做个笔记,题目是我自己加 ...

  7. JavaScript 中的尾调用

    尾调用(Tail Call) 尾调用是函数式编程里比较重要的一个概念,它的意思是在函数的执行过程中,如果最后一个动作是一个函数的调用,即这个调用的返回值被当前函数直接返回,则称为尾调用,如下所示: f ...

  8. 深度递归必须知道的尾调用(Lambda)

    引导语 本文从一个递归栈溢出说起,像大家介绍一下如何使用尾调用解决这个问题,以及尾调用的原理,最后还提供一个解决方案的工具类,大家可以在工作中放心用起来. 递归-发现栈溢出 现在我们有个需求,需要计算 ...

  9. javascript专题系列--尾调用和尾递归

    最近在看<冴羽的博客>,讲真,确实受益匪浅,已经看了javascript 深入系列和专题系列的大部分文章,可是现在才想起来做笔记.所以虽然很多以前面试被问得一脸懵逼的问题都被“一语惊醒梦中 ...

随机推荐

  1. 吞吐量(TPS)、QPS、并发数、响应时间(RT)

    1. 响应时间(RT)  响应时间是指系统对请求作出响应的时间.直观上看,这个指标与人对软件性能的主观感受是非常一致的,因为它完整地记录了整个计算机系统处理请求的时间.由于一个系统通常会提供许多功能, ...

  2. MySQL用另一张表的字段值Update本表

    SQL示例: UPDATE TABLE1 a, TABLE2 b SET a.field1 = b. field1 [, a.field2 = b.field2, ...] WHERE a.connn ...

  3. KAFKA官方教程笔记-introduction

    为什么80%的码农都做不了架构师?>>>   介绍 apache kafka是一个分布式流式处理平台,一个流式平台该有的三个关键能力: 发布.订阅流式数据.从这个角度讲类似消息队列或 ...

  4. 数学--数论--随机算法--Pollard Rho 大数分解算法 (带输出版本)

    RhoPollard Rho是一个著名的大数质因数分解算法,它的实现基于一个神奇的算法:MillerRabinMillerRabin素数测试. 操作流程 首先,我们先用MillerRabinMille ...

  5. The Preliminary Contest for ICPC Asia Xuzhou 2019 徐州网络赛 A Who is better?

    A After Asgard was destroyed, tanker brought his soldiers to earth, and at the same time took on the ...

  6. select函数的使用

    select函数是 I/O 复用中非常重要的一个函数,属于并发编程的.它能够监视我们需要监视的文件描述符的变化情况–读.写或者异常 1. 函数原型 #include <sys/select.h& ...

  7. libevent(九)evhttp

    用libevent构建一个http server非常方便,可参考libevent(六)http server. 主要涉及的一个结构体是evhttp: struct evhttp { /* Next v ...

  8. C# 9.0 新特性预览 - 空参数校验

    C# 9.0 新特性预览 - 空参数校验 前言 随着 .NET 5 发布日期的日益临近,其对应的 C# 新版本已确定为 C# 9.0,其中新增加的特性(或语法糖)也已基本锁定,本系列文章将向大家展示它 ...

  9. 单片机之静态局部变量static

    HL-1慧静电子 上程序: main.c #include <reg52.h>#include "Timer.h" /********P1口低有效*********** ...

  10. [hdu4497]分解质因数

    题意:求满足gcd(x,y,z)=G,lcm(x,y,z)=L的x,y,z的解的个数. 大致思路:首先如果L % G != 0那么无解,否则令u = L / G,问题变为,gcd(r,s,t)=1,l ...