近期将主力环境从macOS切换至Arch Linux,然后将博客从原环境迁移至现环境,本来以为过程会比较简单,结果却还是踩了几个坑,现在将配置过程中遇到的问题记录并且总结如下。

在Arch Linux中安装Git和Node.js

根据Hexo官方文档的说明,安装Hexo需要的依赖为Git和Node.js。
Git的安装比较简单,使用Arch Linux的默认包管理器pacman即可安装:

1
$ pacman -S git

Node.js官方文档推荐使用nvm安装,并且官方文档给出了安装脚本。
但是我的电脑使用的是伪fish——参考Arch Wiki,我通过的是通过给terminal emulator添加参数的方式进入fish的。
因此,我的默认shell仍然是bash。而该安装脚本在检测到我的默认shell之后直接将相关的导出环境变量的命令添加至了.bashrc,导致了进入fish之后由于相关的环境变量丢失无法找到nvm命令的问题。

  1. 第一种解决方法是采用Node.js的fish版安装脚本,该脚本托管在Github上,但是该脚本目前已不再被MAINTAINED,需要自行承担风险。
  2. 第二种解决方法是采用bass包装原始的nvm。

对于第二种解决方法,我们首先使用官方文档的安装脚本安装nvm:

1
$ wget -qO- https://raw.github.com/creationix/nvm/master/install.sh | sh

然后我们按照Github上的教程手动安装bass:
1
2
3
$ git clone https://github.com/edc/bass.git
$ cd bass
$ make install

最后我们建立如下的文件并重启终端,即可正常地在fish中使用nvm:
1
2
3
4
$ cat ~/.config/fish/functions/nvm.fish
function nvm
bass source ~/.nvm/nvm.sh --no-use ';' nvm $argv
end

使用nvm安装Node.js最新版本的命令如下:
1
$ nvm install v8.1.3

最后我们安装hexo:
1
$ npm install -g hexo-cli

hexo server报EMFILE错误

报错内容如下:

1
Error: EMFILE, too many open files

Hexo官网的问题解答中给出了如下描述:
虽然 Node.js 有非阻塞 I/O,同步 I/O 的数量仍被系统所限制,在生成大量静态文件的时候,您可能会碰到 EMFILE 错误,您可以尝试提高同步 I/O 的限制数量来解决此问题。
1
$ ulimit -n 10000

但是当我尝试使用ulimit的时候,却报了如下的错误:
1
Permission denied when changing resource of type 'Maximum number of open file descriptors'

在这之后进行了如下的尝试:

  1. 使用sudo无法运行ulimit,后su至root运行,虽然没有报错,但是使用ulimit -n查看发现修改失败。
  2. 尝试添加参数-S和-H,没有效果。
  3. 最后根据Arch Forum上的回答,修改了/etc/security/limits.conf文件并重启电脑,问题解决。

hexo server报ENOSPC错误

Hexo官网的问题解答中给出了如下描述:
它可以用过运行 $ npm dedupe 来解决,如果不起作用的话,可以尝试在 Linux 终端中运行下列命令:

1
$ echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf && sudo sysctl -p

这将会提高你能监视的文件数量。
$ npm dedupe没有解决问题,最后使用上述的命令解决了问题。(注意在fish中,'&&'要用'COMMAND; and COMMAND'来替代)

评论和共享

iOS学习笔记(一)

发布在 iOS开发

最近开始了自己的第一个项目,到目前为止已经写完了基本的界面,将开发过程中遇到的一些问题列举如下:

自定义cell分割线

首先设置 tableView.separatorStyle = UITableViewCellSeparatorStyleNone;

然后在自定义的cell的实现文件内实现如下的方法

1
2
3
4
5
6
7
8
9
10
11
12
- (void)drawSeparator{
_separatorlineLayer = [CAShapeLayer layer];
CGMutablePathRef separatorShapePath = CGPathCreateMutable();
[_separatorLayer setFillColor:[UIColor clearColor].CGColor];
[_separatorLayer setStrokeColor:[UIColor headlineColor].CGColor];
_separatorLayer.lineWidth = 0.5f;
CGPathMoveToPoint(separatorShapePath, NULL, 0.0f, 0.0f);
CGPathAddLineToPoint(separatorShapePath, NULL, WIDTH, 0.0f);
[_headlineLayer setPath:separatorShapePath];
CGPathRelease(separatorShapePath);
[self.contentView.layer addSublayer:_separatorLineLayer];
}

其中,_separatorLayerCAShapeLayer的实例,setStrokeColor方法设定了线的颜色,CGPathMoveToPointCGPathAddLineToPoint设定了线的起始点。

同理,可以类似地实现画点或者更为复杂形状的效果。

iOS8之后cell的动态高度计算

首先使用autolayout布局,且确保cell的contentView至少top和bottom都和cell内部的View建立了约束。之后添加如下代码

1
2
tableView.estimatedRowHeight = 60.0f;
tableView.rowHeight = UITableViewAutomaticDimension;

需要注意的是,必须要为tebleView的estimiatedRowHeight属性设定值。

返回键盘的高度

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
- (void)viewDidLoad{
[super viewDidLoad];
//注册通知
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
}

- (void)dealloc {
//移除通知
[[NSNotificationCenter defaultCenter]removeObserver:self];
}

- (void)keyboardWillShow:(NSNotification *)notification{
//键盘弹出时调用
NSDictionary * userInfo = [notification userInfo];
NSValue * frameValue = [userInfo objectForKey:UIKeyboardFrameEndUserInfoKey];
CGRect keyboardRect = [frameValue CGRectValue];
NSInteger height = keyboardRect.size.height;
}

- (void)keyboardWillHide:(NSNotification *)notification{
//键盘隐藏时调用
}

height中储存的即为当前键盘的高度

小心block导致的retain cycle

如果在block中需要访问本类的实例变量,需要使用

__weak UIViewController * weakSelf = self;

self持有了block,而block通过捕获self来访问实例变量,导致保留换的产生,通过__weak打破保留环。

评论和共享

  • 第 1 页 共 1 页
作者的图片

码龙黑曜

iOS开发者/计算机科学/兽人控


华中科技大学 本科在读


Wuhan, China