0%

先决条件:

  • 服务器购买(我用的是 vultr
  • 域名购买并解析(我用的是 DNSpod

这里服务器的系统是: Ubuntu 18.04

Nginx安装

  1. 先更新软件包列表,再安装 Nginx

    1
    2
    sudo apt-get update
    sudo apt-get install nginx
  2. 安装完成后,打开浏览器,输入服务器 http://server_domain_or_ip 地址,如下图所示,则说明安装成功

    Nginx安装成功

  3. 也可以通过检查服务状态(安装完成后,Nginx服务自动启动),如下图所示,则说明安装成功

    1
    sudo systemctl status nginx		

    Nginx安装状态检查

配置Nginx

建议: 一般情况下,将要托管在服务器上的每个 /var/www 目录中创建一个单独的目录,用于存储对应网站的文件。

常见管理 Nginx 服务命令

1
2
3
4
5
6
7
sudo nginx -t		# 检查 Nginx 配置是否正确
sudo systemctl stop nginx # 停止服务
sudo systemctl start nginx # 启动服务
sudo systemctl restart nginx # 重启服务
sudo systemctl reload nginx # 重新加载配置
sudo systemctl disable nginx # 禁用服务
sudo systemctl enable nginx # 重新启用服务

配置 Hexo 域服务

阅读全文 »

关于 iOS 原生项目集成 Unity 项目的处理,网上有很多教程,这里不讨论这个。这里想要说的是 如何自动化处理 Unity 代码更新至 iOS 工程中

常规Unity 代码更新时,都要经过以下步骤:

  1. Unity 代码编译生成对应的 Unity_iOS 工程
  2. Unity_iOS 工程更新的代码(一般都是:LibrariesClassesData 这三个目录的文件数据更新)合并到原生iOS 工程
  3. 原生的 iOS 工程添加相应的接口处理。。。

这其中第二步的 合并 步骤,其实包含了很多相似重复性的工作,每次都是代码文件的 曾、删、改 ;在常规的使用 BeyondCompare 可以满足当前需求。但是如果频繁需要更新 Unity 代码,那就不能保证每次手工比对代码已经添加文件不会出错,而且还加重了工作负担,因此决定做一个 脚本 脚本来自动化处理。

Unity 代码更新处理流程

继续细化 合并 步骤,又可以分为以下:

  • 新增 Unity 文件
  • 删除 Unity 文件
  • 修改 Unity 文件

对于这几个操作需求,shell就可以满足这要求,大体思路如下:

遍历 Unity 工程文件和 iOS 工程文件(主要是 LibrariesData、文件夹以及 Classes 目录下的Native子文件夹 ),对于 新增修改 的文件,可以直接 cp,同时记录新加的 文件/文件夹,对于删除的文件,可以直接 rm,同时记录删除的 文件/文件夹 即可。

于是就写了一个脚本如下:

阅读全文 »

arm64 汇编准备

寄存器

通用寄存器

31R0 ~ R30,每个寄存器可以存取一个 64 位大小的数。 当使用 x0 - x30访问时,是一个 64位的数;当使用 w0 - w30访问时,是一个 32 位的数,访问的是寄存器的 32,如图:

向量寄存器

(也可以说是 浮点型寄存器)每个寄存器的大小是 128 位的。 分别可以用Bn Hn Sn Dn Qn的方式来访问不同的位数;如图:

注:word 是 32 位,也就是 4 Byte大小。

  • Bn:一个 Byte的大小,即 8
  • Hn:half word,即 16
  • Sn:single word,即 32
  • Dn:double word,即 64
  • Qn:quad word,即128
阅读全文 »

之前收到了七牛发的测试域名回收通知邮件,当时没太在意,以为域名过期了,再申请续一下就行。结果发现域名回收后,博客里面用的七牛的免费图床全部过期了,所有图片全都不可以访问了;当时内心是无比崩溃的。。。

QiNiuDomainTakeBack.png

于是乎,各番搜索,发现 Chevereto 免费版 是个不错的选择,就打算搭建一个属于自己的 图床 ,根据其要求,需要具备以下几个条件:

  • Apache / NGiNX web server
  • PHP 5.5.0 (standard libraries)
  • MySQL 5.0 (ALL PRIVILEGES)

声明: 本人搭建是在 Vultr 的一台机器 (Ubuntu _16.04) 上搭建的。

NGINX

  1. 安装 Nginx:

    1
    2
    3
    cd /usr/local
    apt-get update
    apt-get install nginx

    安装Nginx

  2. 打开浏览器,输入服务器 http://server_domain_or_IP 地址,如下图所示,则说明安装成功

    Nginx访问页

MySQL

  1. 安装MySQL

    1
    2
    3
    cd /usr/local
    apt-get update
    apt-get install mysql-server

    安装MySQL

  2. 设置 MySQL root 密码:********

  3. 安装完成

    MySQL完成完整

PHP-7

  1. 安装 PHP-7.0

    1
    2
    3
    cd /usr/local
    apt-get update
    apt-get -y install php7.0-fpm php-mysql

    PHP完成安装

  2. PHP fix_pathinfo 潜在安全漏洞,在 /etc/php/7.0/fpm/php.ini 中找到 ;cgi.fix_pathinfo=1

  3. 修改为:**cgi.fix_pathinfo=0**

  4. 重启 php

    1
    systemctl restart php7.0-fpm
  5. 配置 Nginx-PHP:vi /etc/nginx/sites-available/default 添加如下配置:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    server {
    listen 80;
    listen [::]:80;

    # listen [::]:443 ssl http2;
    # listen 443 ssl http2;

    # include ssl.conf;
    # ssl_certificate /path/to/crt;
    # ssl_certificate_key /path/to/key;

    root /var/www/server_domain_or_IP;
    index index.html index.htm index.php;

    server_name server_domain_or_IP;

    location / {
    try_files $uri $uri/ =404;
    }

    location /phpmyadmin {
    index index.php;
    }

    location ~ \.php$ {
    include snippets/fastcgi-php.conf;
    fastcgi_pass unix:/run/php/php7.0-fpm.sock;
    }

    location ~ /\.ht {
    deny all;
    }
    }
  6. 配置前内容截图如下:

  7. 配置后内容截图如下:

  8. 重启 Nginx

    1
    systemctl restart nginx
  9. 测试PHP是否已完成安装配置,添加 info.php

    1
    vi /var/www/html/info.php
  10. 添加内容

    1
    2
    3
    <?php
    phpinfo();
    ?>
  11. 然后访问: http://server_domain_or_IP/info.php 出现下图则安装配置成功

阅读全文 »

考虑以下代码,最终会输出什么?

例子①:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
- (void)viewDidLoad
{
[super viewDidLoad];

NSLog(@"1 - %@", [NSThread currentThread]);

dispatch_async(dispatch_get_global_queue(0, 0), ^{

NSLog(@"2 - %@", [NSThread currentThread]);
[self performSelector:@selector(test)
withObject:nil];
NSLog(@"4 - %@", [NSThread currentThread]);
});
}

- (void)test
{
NSLog(@"3 - %@", [NSThread currentThread]);

}
  • 输出结果:1,2,3,4
  • 原因:因为 performSelector:withObject: 会在当前线程立即执行指定的 selector 方法。

例子②:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
- (void)viewDidLoad
{
[super viewDidLoad];

NSLog(@"1 - %@", [NSThread currentThread]);

dispatch_async(dispatch_get_global_queue(0, 0), ^{

NSLog(@"2 - %@", [NSThread currentThread]);
[self performSelector:@selector(test)
withObject:nil
afterDelay:0];
NSLog(@"4 - %@", [NSThread currentThread]);
});
}

- (void)test
{
NSLog(@"3 - %@", [NSThread currentThread]);
}
  • 输出结果:1,2,4
  • 原因:因为 performSelector:withObject:afterDelay: 实际是往 RunLoop 里面注册一个定时器,而在子线程中,RunLoop 是没有开启(默认)的,所有不会输出 3。官网 API 作如下解释:
    PerformSelectorAfterDelay.png

例子③:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
- (void)viewDidLoad
{
[super viewDidLoad];

NSLog(@"1 - %@", [NSThread currentThread]);

dispatch_async(dispatch_get_global_queue(0, 0), ^{

NSLog(@"2 - %@", [NSThread currentThread]);
[self performSelector:@selector(test)
withObject:nil
afterDelay:0];
[[NSRunLoop currentRunLoop] run];
NSLog(@"4 - %@", [NSThread currentThread]);
});
}

- (void)test
{
NSLog(@"3 - %@", [NSThread currentThread]);
}
  • 输出结果:1,2,3,4
  • 原因:由于 [[NSRunLoop currentRunLoop] run]; 会创建的当前子线程对应的 RunLoop 对象并启动了,因此可以执行 test 方法;并且 test 执行完后,RunLoop 中注册的定时器已经无效,所以还可以输出 4 (对比 例子⑥例子)。
阅读全文 »

H.264,又称为 MPEG-4 第10部分,高级视频编码(英语:MPEG-4 Part 10, Advanced Video Coding,缩写为 MPEG-4 AVC)是一种面向块,基于 运动补偿 的视频编码标准(可以被视为由多个不同的应用框架 / 配置文件(profiles)组成的“标准系列”)。

视频的编码方式

视频编码: 其本质就是将数据压缩,主要是去除冗余信息(包括 空间 上的冗余信息和 时间 上的冗余信息),从而实现数据量的压缩。

  1. 空间冗余: 在同一图像(帧)内,相近像素之间的差别很小(甚至是相同的),所以就可以用一个特定大小的像素矩阵来表示相邻的像素。
  2. 时间冗余: 视频中连续的图像(帧)之间,其中发生变化的像素占整张图像像素的比例极其微小,所以就可以用其中一帧来表示相邻的帧来减少带宽消耗。
  3. 编码冗余: 不同像素出现的概率不同,所以就可以为出现概率高的像素分配尽量少的字节,对出现概率低的像素分配尽量多的字节。
  4. 视觉冗余: 人眼对很多像素颜色不敏感,所以就可以丢弃这些冗余的信息而并不影响人眼观看的效果。

帧间编码

帧间编码: 可以去除 时间 上的冗余信息。

  1. 运动补偿: 通过先前的局部图像来预测、补偿当前的局部图像(是减少帧序列冗余信息的有效方法)。
  2. 运动表示: 不同区域的图像需要使用不同的运动矢量来描述运动信息。
  3. 运动估计: 从视频序列中抽取运动信息的一整套技术。

帧内编码

帧内编码: 可以去除 空间 上的冗余信息。

帧类别

阅读全文 »

YUV

简述

YUV:是一种颜色空间,基于 YUV 的颜色编码是流媒体的常用编码方式,这种表达方式起初是为了彩色电视与黑白电视之间的信号兼容;其中

  • Y:表示明亮度(Luminance 或 Luma),也称灰度图。
  • U、V:表示色度(Chrominance 或 Chroma),作用是描述影像的色彩及饱和度,用于指定像素的颜色。

Y’CbCr:(也称为 YUV),是 YUV 的压缩版本,不同之处在于 Y’CbCr 用于 数字图像 领域,YUV 用于 模拟信号 领域;MPEGDVD、摄像机中常说的 YUV 其实是 Y'CbCr,二者转换为 RGBA 的转换矩阵是不同的。

  • Cr:(色度红)反应了 RGB 输入信号 红色 部分与 RGB 信号亮度值之间的差异(即,当前颜色对 红色 的偏移程度)。

  • Cb:(色度红)反应了 RGB 输入信号 蓝色 部分与 RGB 信号亮度值之间的差异(即,当前颜色对 蓝色 的偏移程度)。

    图片来源于:https://en.wikipedia.org/wiki/YUV

注意:如无特殊说明,本文讨论的 YUV 均指 Y'CbCr

格式

YUV存储格式:

  • planar:先存储 Y,然后 U,然后 V
  • packed:yuv 交叉存储。
阅读全文 »

在 iOS 的界面中,通常都是使用 UIView 来进行绘制 UI,但其底下最终还是通过 CALayer 来进行绘制。

UIView 和 CALayer 区别与联系

  • 所属的框架不同:UIViewUIKit 的(只能 iOS 使用),CALayerQuartzCore 的(iosMacOS 通用);
  • UIViewCALayer 的事件代理(即,UIView 可以响应触摸事件,CALayer 则无法响应触摸事件);
  • 各自都有对应的图层树结构;
  • 每个 UIView 实例对象都对应有一个 CALayer 实例对象;
  • UIView 可以看做是 CALayer 的管理者;

CALayer 的基本属性

类型 名称 用途
CGRect bounds 大小
CGPoint position 描点在父 layer 的位置(父 layer 的坐标系)
CGPoint anchorPoint 锚点位置(当前 layer 的坐标系),取值范围:0~1
CATransform3D transform 变换,是一个矩阵(可以理解为结构体)
id contents 内容(可以设置为图片,但是需要桥接)
CGFloat borderWidth 边宽
CGColorRef borderColor 边的颜色
CGColorRef backgroundColor 背景颜色
float opacity 透明度
CGColorRef shadowColor 阴影颜色
float shadowOpacity 阴影透明度,设置范围 0~1
CGSize shadowOffset 阴影的偏移
CGFloat shadowRadius 阴影的模糊度
CGFloat cornerRadius 圆角
BOOL masksToBounds 超过部分进行是否裁剪

positionanchorPoint

  • position 表示 描点在父 layer 的位置(基于父 layer 的坐标系),默认情况下 position 相当于 UIViewcenter
  • anchorPoint 表示 position 在当前 layer 的位置(基于当前 layer 的坐标系),取值范围:0~1

更详细的解说可以参见这里

隐式动画

  • 当对非 Root Layer 的部分属性(如:bound、position。。。)进行修改时,默认会自动产生一些动画效果。

    CALayer 隐式动画

  • 关闭隐式动画:可以通过动画事务(CATransaction)关闭默认的隐式动画效果,步骤如下:

    • 开启动画事物;

    • 关闭动画效果或者修改动画事件;

    • 设置动画完成后的动作(可以不设置);

    • 修改属性;

    • 提交;

      1
      2
      3
      4
      5
      6
      7
      8
      // 开启
      [CATransaction begin];
      // 关闭动画
      [CATransaction setDisableActions:YES];
      // 修改属性
      subView.layer.position = CGPointMake(10, 10);
      // 提交
      [CATransaction commit];
阅读全文 »

图形界面安装

  1. 登录 Cmake 官网,进入 下载页面

  2. 下载 MacOS 平台对应的安装包,我当时下载的是 cmake-3.9.0-Darwin-x86_64.dmg

  3. 下载完成后,安装 dmg,成功后打开界面如下:

命令行安装

GUI 版的 CMake 安装好之后,安装命令行 CMake 就简单好多了:

  1. 运行 CMake 图形界面程序,在左上角的选项栏中选择 Tools,点击 How to Install For Command Line Use

  2. 此时弹出来一个消息框:

    这是官方给出了三种安装 cmake command line tool 的方法,即终端能够识别 cmake命令的方法,选择其中 1 中即可。

  3. 打开终端,输入:

    1
    $ sudo "/Applications/CMake.app/Contents/bin/cmake-gui" --install

  4. 至此,命令行的 cmake 已经安装成功

    • 安装前:

    • 安装后:

阅读全文 »

如果不了解 iOS 的签名机制的,请翻看 iOS 打包预备

开发者账号

准备一个已经付费的开发者账号;开发者账号类型主要有 4 类:

  1. 个人(Individual):年资费 $99,在 App Store 销售者只能显示个人的 ID,单人使用;且只能有一个开发者,100个 iOS设备 UDID 测试。
  2. 公司(Company):年资费 $99,申请时需要填写公司的邓白氏编码(D-U-N-S);在 App Store 销售者可以显示团队名称,允许多个开发者协作开发,100个 iOS设备 UDID 测试,比个人多一些帐号管理的设置,可以设置多个 AppleID,分 4 种管理级别权限:
    • Admin Legal:超级管理员。可以管理开发者和管理 App Store 中的应用。
    • Admin:管理员,可以管理开发者;添加测试机子和管理团队证书。
    • Member权限:是普通开发者;只能下载证书和使用证书
    • No Access权限:没有相应的权限。
  3. 企业(Enterprise):年资费 $299,开发应用不能发布到 App Store,只能企业内部应用,iOS 设备 UDID 测试的数量不限制。
  4. 高校(University):免费,只能教育机构或学院内部使用。(必须是苹果 iOS 开发者计划授权机构;不能对外正式发布iOS应用程序。)

证书

  1. 开发证书(Development):真机运行使用。
  2. 发布证书(Distribution):打包 App 使用。

条件

  1. 真机运行:发者账号。
  2. 打包测试/发布 :开发者账号 + 发布证书( Certificates) + 配置文件(Provisioning Profiles)。

打包

创建 CSR 文件

阅读全文 »