const

Autorelease对象什么时候释放?

故事扮演 提交于 2020-03-07 18:32:25
Autorelease机制是iOS开发者管理对象内存的好伙伴,MRC中,调用 [obj autorelease] 来延迟内存的释放是一件简单自然的事,ARC下,我们甚至可以完全不知道Autorelease就能管理好内存。而在这背后,objc和编译器都帮我们做了哪些事呢,它们是如何协作来正确管理内存的呢?刨根问底,一起来探究下黑幕背后的Autorelease机制。 原文链接 Autorelease对象什么时候释放? 这个问题拿来做面试题,问过很多人,没有几个能答对的。很多答案都是“当前作用域大括号结束时释放”,显然木有正确理解Autorelease机制。 在没有手加Autorelease Pool的情况下,Autorelease对象是在当前的 runloop 迭代结束时释放的,而它能够释放的原因是 系统在每个runloop迭代中都加入了自动释放池Push和Pop 小实验 __weak id reference = nil; - (void)viewDidLoad { [super viewDidLoad]; NSString *str = [NSString stringWithFormat:@"sunnyxx"]; // str是一个autorelease对象,设置一个weak的引用来观察它 reference = str; } - (void)viewWillAppear:

C++注意的东西

流过昼夜 提交于 2020-03-07 18:31:29
1.C++的const类成员函数 C++中,若一个变量声明为const类型,则试图修改该变量的值得操作都被看做编译错误。 例如:const char blank = '';    blank = '\n';//错误 面向对象程序设计中,为了体现封装性,通常不允许直接修改类对象的数据程序。若要修改对象, 应调用公有成员函数来完成。为了保证const对象的常量性,编译器须区分不安全与安全的成员函数。 在C++中,只有被声明为const的成员函数才能被一个const类对象调用。要声明一个const类型的类成员函数, 只需要在成员函数参数列表后加上关键字const, 例如: class Screen { public : char get() const; }; 在类体之外定义const成员函数时,还必须加上const关键字 例如: char Screen::get() const { return _screen[_cursor]; } 若将成员函数声明为const,则该函数不允许修改类的数据成员。 例如: class Screen { public : int OK() const {return _cursor;} int ERROR(int ival) const{_curso = ival;} } 在上面成员函数的定义中,OK()的定义是合法的,ERROR()的定义则非法。 小结

EcmaScript 6 十大常用特性

杀马特。学长 韩版系。学妹 提交于 2020-03-07 16:11:04
以下是ES6排名前十的最佳特性列表(排名不分先后): Default Parameters(默认参数) in ES6 Template Literals (模板文本)in ES6 Multi-line Strings (多行字符串)in ES6 Destructuring Assignment (解构赋值)in ES6 Enhanced Object Literals (增强的对象文本)in ES6 Arrow Functions (箭头函数)in ES6 Promises in ES6 Block-Scoped Constructs Let and Const(块作用域构造Let and Const) Classes(类) in ES6 Modules(模块) in ES6 声明:这些列表仅是个人主观意见。它绝不是为了削弱ES6其它功能,这里只列出了10条比较常用的特性。 1.Default Parameters(默认参数) in ES6 还记得我们以前不得不通过下面方式来定义默认参数: 1 var link = function (height, color, url) { 2 var height = height || 50; 3 var color = color || 'red'; 4 var url = url || 'http://azat.co'; 5 ... 6

es6新特性---let const

前提是你 提交于 2020-03-07 11:48:31
想要学习更多,推荐看阮大神的http://es6.ruanyifeng.com/#docs/let 在学习之前得知道作用域 ES5 中作用域有:全局作用域、函数作用域。没有块作用域的概念。 ES6 中新增了块级作用域。块作用域由 { } 包括,if语句和 for语句里面的{ }也属于块作用域。 ES6 允许块级作用域的任意嵌套 let命令 ES6 新增的 let 命令,可以用来声明变量。它的用法类似于 var ,但是所声明的变量,只在 let 命令所在的代码块内有效。 let命令适合用在for循环中,计数器 i 只在 for 循环体内有效,在循环体外引用就会报错 不存在变量提升 var 命令会发生”变量提升“现象,即变量可以在声明之前使用,值为 undefined 。 let 命令改变了语法行为,它所声明的变量一定要在声明后使用,否则报错。 不允许重复声明 let 不允许在相同作用域内,重复声明同一个变量。 const命令 const 声明一个只读的常量。一旦声明,常量的值就不能改变。 来源: oschina 链接: https://my.oschina.net/u/3869887/blog/1920589

第二章 工作量证明和挖矿

时光毁灭记忆、已成空白 提交于 2020-03-07 09:56:00
概览 工作量证明拼图和难易度 挖矿 难易度共识 时间戳校验 累积难易度 验证测试 小结 概览 本章节我们将会在我们的玩具版区块链的基础上加入工作量证明(POW)的支持。在 第一章节 的版本中, 任何人都都可以在没有任何工作量证明的情况下添加一个区块到区块链中。 当我们引入工作量证明机制之后,一个节点必须要解开一个有相当计算量的拼图(POW Puzzle)之后,才能往区块链上添加一个新的区块。而去解开该拼图,通常就被称为挖矿。 引入工作量证明机制之后,我们还可以对一个新区块的产出时间作出大致的控制。大概的做法就是动态的改变拼图的难易程度来达到控制的效果:如果最近的区块产生的太快了,那么就将拼图的难度提升,反之,则将拼图的难度降低。 需要点出来的时,本章节中我们还没有引入 交易(Transaction) 这个概念。这就意味着矿工挖出一个区块后,并不会获得相应的奖励。 一般来说,在加密货币中,如果矿工挖到了一个区块,是应该获得一定量的币作为激励的。 工作量证明拼图和难易度 在上一个章节的区块链的基础上,我们将会为区块结构加入两个新的属性:difficulty和nonce。要弄清楚这俩货是干嘛用的,我们必须先对工作量证明拼图作一些必要的阐述。 工作量证明拼图是一个什么样的任务呢?其实就是去计算出一个满足条件的区块哈希。怎么才算满足条件呢?如果这个计算出来的哈希的前面的0的数目满足指定的个数

javascript计算两条直线的夹角

倾然丶 夕夏残阳落幕 提交于 2020-03-07 08:45:26
计算上面两直线的夹角,代码如下 const getAngle = ({ x: x1, y: y1 }, { x: x2, y: y2 }) => { const dot = x1 * x2 + y1 * y2 const det = x1 * y2 - y1 * x2 const angle = Math.atan2(det, dot) / Math.PI * 180 return (angle + 360) % 360 } const angle = getAngle({ x: x1 - x3, y: y1 - y3, }, { x: x2 - x3, y: y2 - y3, }); console.log(angle); 来源: https://www.cnblogs.com/ystrdy/p/10324466.html

Linux设备驱动程序学习——USB 驱动程序(三)

走远了吗. 提交于 2020-03-07 04:43:01
(本部分的一些示例源码来自 drivers/usb/usb-skeleton.c ,它是Linux内核为我们提供的最基础的USB驱动程序,USB骨架程序) 驱动程序把驱动对象注册到 USB 子系统中,之后使用供应商(idVendor)和设备(idProduct)标识来判断对应的硬件是否已经安装. 驱动的设备支持列表 struct usb_device_id 结构提供了这个驱动支持的不同类型 USB 设备的列表. USB 核心通过此列表用来决定设备对应的驱动,热插拔脚本也通过此列表来决定当特定设备被插入系统时,应该自动加载的驱动. struct usb_device_id { /* 确定设备信息去和结构体中哪几个字段匹配来判断驱动的适用性 */ __u16 match_flags ; /* Used for product specific matches; range is inclusive */ __u16 idVendor ; //USB设备的制造商ID,须向 www.usb.org 申请 __u16 idProduct ; //USB设备的产品ID,有制造商自定 __u16 bcdDevice_lo ; /* USB设备的产品版本号最低值*/ __u16 bcdDevice_hi ; /* 和最高值,以BCD码来表示。*/ /* 分别定义设备的类,子类和协议,他们由 USB

element 中的table表头动态渲染

自作多情 提交于 2020-03-07 02:38:47
element 中的table表头动态渲染 实际开发过程中遇到需求,表格中表头不一定是固定的,表头需要动态渲染。 <el-table :data="this.tableData" height="525"> <el-table-column v-for="(item, index) in tableLabel" :key="index" :prop="item.prop" :width="item.width" :label="item.label"> </el-table-column> </el-table> 这里的height="525"是为了固定头部 tableData: [// 表数据 { id: 1, date: '2018-07-24', sales: 23.34, sale: 137597.76, const: 102203.71, profit: 35394.05 }, { id: 2, date: '2018-07-24', sales: 23.34, sale: 137597.76, const: 102203.71, profit: 35394.05 }, { id: 3, date: '2018-07-24', sales: 23.34, sale: 137597.76, const: 102203.71, profit: 35394.05 }, { id

Qt开发MQTT(二) 之第三方QMQTT

若如初见. 提交于 2020-03-07 00:02:59
概述 上一篇文章 已经介绍了Qt官方提供的MQTT封装的使用方式,除此之外,还有另外一个第三方的公司也提供了针对MQTT的Qt封装接口,其使用方式都差不多,只是接口名称有些变化,这里也简单的介绍一下,可以根据个人喜好来选择使用那种方式。 官网地址: https://www.emqx.io/cn/ 下载编译 EMQ也提供了源码供大家下载使用, 地址在这里 我们将源码下载后进行编译,编译过程和上一篇文章介绍的差不多,这里就不再详细讲了。 我们使用Release模式编译后,同样也会得到和之前一样的生成文件: 根据 前一篇文章 的步骤我们将生成库部署到Qt的安装目录。 注意:这两种对MQTT的封装的源码编译生成出来的库名称是一样的,但是提供的接口不一样,所以如果编译了这两种源码,不要全部都部署到Qt安装目录,会覆盖的。如果编译了两份源码并且都想尝试使用, 那么可以将一个部署到Qt安装目录,另一个直接用外部库的方式导入到测试测试项目中进行使用,这两种方法都已经在前一篇文章中详细介绍过了。 接口 EMQ提供的这个MQTT的封装就不像Qt官方提供的那样完善了,我目前找到的也就只有github上的简短介绍,但其实我们有了源码,要去看相应的接口还是挺方便的。在源码里面对每个接口介绍挺详细的。 那么它提供的主要接口有以下这些: 槽 void setHost ( const QHostAddress &

【图论】欧拉回路

五迷三道 提交于 2020-03-06 23:58:03
先上一个板子吧,单向的 # include <bits/stdc++.h> # define ll long long # define endl '\n' using namespace std ; const int INF = 0x3f3f3f3f ; const int mod = 1e9 + 7 ; const int maxn = 1e3 + 10 ; int tot , n , m , cnt ; int head [ maxn ] , vis [ maxn ] , ans [ maxn ] ; struct E { int to , next ; } edge [ maxn << 1 ] ; void add ( int u , int v ) { edge [ tot ] . to = v ; edge [ tot ] . next = head [ u ] ; head [ u ] = tot ++ ; } void dfs ( int now ) { for ( int i = head [ now ] ; i != - 1 ; i = edge [ i ] . next ) { if ( ! vis [ i ] ) { vis [ i ] = 1 ; dfs ( edge [ i ] . to ) ; ans [ cnt ++ ] = edge [ i ]