嘿妈妈
明天我就要出发了
出发去远方冒险
在那个太阳初升的清晨六点
嘿妈妈
今天到了新的城市
这里路很窄房子却很大
听说年轻时你也来过这里是吗?
嘿妈妈
昨天遇到了一个姑娘
她笑起来很甜
我们谈了很多,包括未来和理想
嘿妈妈
最近我又换了住所
往西搬了三个街区
和佳还是差十二个时区
嘿妈妈
故事还在继续
像微风清徐
在月下轻语
嘿妈妈
明天我就要出发了
出发去远方冒险
在那个太阳初升的清晨六点
嘿妈妈
今天到了新的城市
这里路很窄房子却很大
听说年轻时你也来过这里是吗?
嘿妈妈
昨天遇到了一个姑娘
她笑起来很甜
我们谈了很多,包括未来和理想
嘿妈妈
最近我又换了住所
往西搬了三个街区
和佳还是差十二个时区
嘿妈妈
故事还在继续
像微风清徐
在月下轻语
写一些不知所以的故事吧,在自己还未搞清世界和人生的时候。
出发的时候最忌讳回头,即使你知道背后还有人在看着你。
因为一些东西太容易被抹去了,所以才劝你一定要留下些什么。
写些不算道理的道理,都是前人所想,换个说法罢了
sudo /opt/bitnami/bncert-tool
AWS Lightsail WordPress的instance已经提前安装好了 bncert-tool, 如果之前已经配置过一次SSL的DNS records 和开启了HTTPS的话,遇到证书过期,只需要执行上面的command。然后他自动跑完之后就会签发证书了
2021-09-23 update
这两天发现之前的认证又失效了,于是准备继续去renew certificate,但是在跑的时候发现会报错说certificate expire,查了很久,刚开始觉得这个是一个悖论,因为expire所以需要renew,但是因为expire又不能renew。 实在头大,后来发现bitnami其实有自己的letencrypt的证书存储地址,所以在/etc/letencrypt/下面的证书并不会生效
最终的解决办法就是把 /opt/bitnami/letencrypt/certificate 下的证书删掉,重新跑就好了
这里我第二次授权的时候使用的是lego,但其实应该certbot也是可以的,只要确保过期的证书被删掉就好
lego在生产证书的时候,会自动生成在./.lego/certificate,所以还需要拷贝到对应的bitnami放证书的地方
doc:
https://go-acme.github.io/lego/usage/cli/examples/
https://docs.bitnami.com/general/how-to/generate-install-lets-encrypt-ssl/
2022-03-04 update
又踩了一个坑,因为renew报错显示需要先revoke 生效的certification,然后再重新申请,所以就直接删除了/opt/bitnami/letenscript/*, 然后发现apache直接down掉了,后来只能重新给apache生成了一个dummy的certificates,然后更改了bitnami的config,再重新生成就好了
https://docs.bitnami.com/aws/apps/wordpress/administration/create-ssl-certificate-apache/
当我们在设计聊天界面的时候,由于聊天记录可能存放在服务端,又或者为了考虑内存的因素,我们偏向于在一开始仅仅展示一部分聊天记录,这时候我们就需要有一个方法来实现加载之前的聊天记录。通常是通过下拉来实现的(例如微信)
和下拉刷新的思想很接近,我们可以选择在tableview上加一个refresh control来实现下拉加载,但这里并不推荐使用这个方法(原因后面会提到)但是无论我们使用哪个方法,当我们获取到新的data的时候,需要把他添加到tableView的最上面,这样才符合逻辑。

由于TableView的特性,在reload的data的时候,会自动跳转到新加入的cell的顶端,也就是上图所示绿色的最顶端,这样就会导致每次加载之后整个tableView都会产生突兀的跳转。
这时候我们需要的解决方法是像参考微信一样,在加入新的Cell的同时,保持我们当时的contentOffset。具体实现这个的代码如下:
let oldContentSizeHeight = ListView.contentSize.height
ListView.reloadData()
ListView.layoutIfNeeded()
let newContentSizeHeight = ListView.contentSize.height
ListView.setContentOffset(CGPoint(x:ListView.contentOffset.x, y:newContentSizeHeight - oldContentSizeHeight), animated: false)
简而言之,就是在reload data之前记录此时的content height,待reload结束之后再记录之后的height,通过相减来设置contentOffset
这时候我们需要了解tableView在计算content height的原理,如果只是简单的单一的cell,那么cell的height会是相同的,并且是在
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { }
这个delegate方法里设定的,但是如果我们的cell是多种类的呢,这时候iOS提供了一个estimate height 对于cell
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableView.automaticDimension
}
通过同时实现这个delegate和上一个delegate的方法,iOS会自动帮我们计算出合适的content height,这样就不会产生有问题height,从而导致跳转出现问题(换句话说,如果你不实现这个方法,那么计算你content height的方法,就是简单的cell number * [cell height])
通过以上方式,我们可以实现固定位置的上拉刷新,回到之前提到的问题,为什么不推荐使用refresh control,原因其实很简答,因为refresh control是通过加载一个新的uiView在tableView上面,然后设定一个阈值,当我们下拉到一定程度会调用。那对于用户的体验来讲,需要一直下拉刷新的话,并不让人愉悦。通常快速向上滑动的时候并不会触发这个调用,也就会导致我们需要很多次“两次操作”才能到达我们想要的聊天记录的位置。那么我这里用到的替代方法是:
func scrollViewDidScroll(_ scrollView: UIScrollView) {
if scrollView == ListView {
if ListView.contentOffset.y < 0 {
if !isLoading {
loadPreviousMessage()
}
}
}
}
因为TableView的实现是在scrollView上的,所以我们可以检测是否scrollView的contentOffset < 0 来检测用户是否想要加载之前的聊天记录,同时因为scrollView的特性是支持bounce的,所以向上快速滑动的同时,contentOffset也会出现 < 0的情况,这里为了避免多次调用,使用了一个变量 “isLoading”来控制。
这样设定之后,我们就可以简单的实现一个向上滑动来加载之前的聊天记录的功能
for un-track a file use:
git update-index --assume-unchanged <path/to/file>
sh: agvtool: command not found
解决办法:
sudo xcode-select -s /Applications/Xcode.app/Contents/Developer
诗里有风
风卷云舒泛着闲适
诗里有雨
雨落三晌心有惆怅
诗里有你
那是心里有你,无他
月亮又在对我笑
轮船在无声地奔逃
栈桥没有脚
却死死地植入大海
大海是张巨大的网
兜住轻飘飘的世界
我沉在海底
月亮在对我笑
对于string来讲,如果是sizeof(std::string) 只有一个成员变量即指向字符串内容的指针,而并没有别的成员变量来记录实际字符串长度了。这个指针是指向内容的地址的
size(string)会返回string里的值,string =[1234567890] string.size() = 10, string.data() = [1234567890]. 指针指向的内存地址上的值是0x1ba8028。也就是说要想知道实际string在内存上占用的大小,需要去看string存的指针指向的内存的大小。