0%

Xcode用久了后会产生很多缓存文件,这些文件会占用很大的磁盘空间.

下面列举的是一些可以删除的文件目录.

  1. ~/Library/Developer/Xcode/DerivedData

    一些中间编译信息文件和debug/release 编译生成的 targets.删除后会重新创建.这里清理后腾出了7.81G

  2. ~/Library/Developer/Xcode/iOS DeviceSupport

    我们每次连上新设备时的『Processing symbol files』就是在向该文件夹写入文件。删除后,再次连上手机时会重新创建.这里清理后腾出了8.68G

    Xcode清理_DeviceSupport

  3. ~/Library/Developer/CoreSimulator

    Apps 在模拟器中的存储文档的位置.这里清理后腾出了13.92G

    Xcode清理_CoreSimulator

  4. /Library/Developer/CoreSimulator/Profiles/Runtimes

    模拟器文件路径.里面是下载的其他版本的模拟器文件.可以删除一些低版本的模拟器.这里清理后腾出了9.6G

    其他版本模拟器文件路径

  5. ~/Library/Developer/Xcode/Archives

    归档项目的存储位置.删除前确保有用的Archive已经备份,因为分析线上崩溃日志需要Archive文件里的一些东西.

其他一些缓存目录:

系统缓存保存在:~/Library/Caches (按需删除)

系统日志保存在:~/Library/Logs

此外,可以使用命令:“sudo du -sh * ”查看当前文件夹下各个文件和文件夹占用的空间大小,进而一步步找到占用磁盘空间较多的文件。

在一些情况下需要对图片进行缩放操作.比如使用iPhone6 Plus拍照得到的将是一张2448x3264的图片,这么大分辨率的图片已经远远超过了手机显示屏的分辨率了,如果直接加载到内存会占用很大的空间,这显然是一种浪费.这个时候就需要等比例缩放图片以减小图片分辨率.一般情况下,即时聊天页面用户发送的图片都会经过分辨率压缩和体积压缩后才会上传到服务器.

由于图片的大小和目标大小比例可能不一致,因此等比例缩放图片到目标尺寸有两种填充方式:

1.等比例填满目标大小,图片可能发生裁剪

两种情况:

1.图片与目标大小宽高比一致.

由于与目标大小宽高比一致,图片缩放后会恰好填满整个目标大小,图片不会发生裁剪.

2.图片与目标大小宽高比不一致.

由于与目标大小宽高比不一致,图片缩放后会超出目标大小,因此图片会发生裁剪.

这里又分为两种情况:

prate < drate,图片会在y轴发生裁剪.

阅读全文 »

口罩类型

纸口罩,活性炭口罩,棉布口罩,海绵口罩.这些口罩因材质不够紧密,无法起到防病毒的效果.

能防病毒的有:一次性医用口罩,医用外科口罩,N95口罩和N95医用防护口罩。

钟南山院士的建议是:并不一定非要戴 N95,因为这些病毒实际上不是单独的存在,它常常存在在飞沫中,一般的口罩、外科口罩等等这些还是能够阻 挡大部分带着飞沫的病毒进入呼吸道。如果是去一般露天公共场所、不与病人接触,可以选择佩戴医用外科口罩,不必过度防护,但如果会接触疑似呼吸道感染的病人,则要佩戴 N95 型口罩。

医用外科口罩

可阻挡血液、体液穿过口罩,能在一定程度上预防呼吸道感染.
购买这一类口罩要注意包装上会有“外科医用口罩”或者是标准为YY-0469-2011.

医用外科口罩真假鉴定

如果没有标注“医用外科口罩”的就别买,
在“国家药品监督管理局”搜索口罩的械注准字号,该字号下的产品规格、批准日期、有效日期等都能被查到.

N95型口罩

N95并不是特定的牌子,N95型口罩是NIOSH(美国国家职业安全卫生研究所,National Institute for Occupational Safety and Health)认证的9种颗粒物防护口罩中的一种。“N”表示不耐油(not resistant to oil)。“95”表示暴露在规定数量的专用试验粒子下,口罩内的粒子浓度要比口罩外粒子浓度低95%以上。其中95%这一数值不是平均值,而是最小值。N95不是特定的产品名称,只要符合N95标准,并且通过NIOSH审查的产品就可以称为“N95型口罩”。防护等级为N95级表示在NIOSH标准规定的检测条件下,口罩滤料对非油性颗粒物(如粉尘、酸雾、漆雾、微生物等)的过滤效率达到95%。

阅读全文 »

更改图片链接上的宽和高(需要服务器支持)

原始图像:

![loading.png](http://upload-images.jianshu.io/upload_images/1503319-c696a9cd1495d68f.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

loading.png

更改大小:

![loading.png](http://upload-images.jianshu.io/upload_images/1503319-c696a9cd1495d68f.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/200)

loading.png

只需要将后面的宽度更改就可以了.这种改链接有效果的原因是因为服务器根据图片链接对原图进行了缩放并返回.这种方案需要服务器支持对图片链接的识别并进行对应的缩放.

使用HTML img标签并设置width和height

Markdown语法:

阅读全文 »

下面的代码:

1
2
3
signed char rs = 240;
BOOL rs1 = 240;
NSLog(@"%d %d", rs, rs1);

在32位机,如iPhone5c上输出为:-16 -16.
在64位机,如iPhone6s上输出为:-16 1.

在SDK usr/include/objc/objc.h里的定义:

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
34
35
36
37
/// Type to represent a boolean value.

#if defined(__OBJC_BOOL_IS_BOOL)
// Honor __OBJC_BOOL_IS_BOOL when available.
# if __OBJC_BOOL_IS_BOOL
# define OBJC_BOOL_IS_BOOL 1
# else
# define OBJC_BOOL_IS_BOOL 0
# endif
#else
// __OBJC_BOOL_IS_BOOL not set.
# if TARGET_OS_OSX || TARGET_OS_MACCATALYST || ((TARGET_OS_IOS || 0) && !__LP64__ && !__ARM_ARCH_7K)
# define OBJC_BOOL_IS_BOOL 0
# else
# define OBJC_BOOL_IS_BOOL 1
# endif
#endif

#if OBJC_BOOL_IS_BOOL
typedef bool BOOL;
#else
# define OBJC_BOOL_IS_CHAR 1
typedef signed char BOOL;
// BOOL is explicitly signed so @encode(BOOL) == "c" rather than "C"
// even if -funsigned-char is used.
#endif

#define OBJC_BOOL_DEFINED

#if __has_feature(objc_bool)
#define YES __objc_yes
#define NO __objc_no
#else
#define YES ((BOOL)1)
#define NO ((BOOL)0)
#endif

大概意思就是:
默认情况下,在32位iPhone上,BOOL就是signed char类型(1个字节。-128 ~ 127)
在64位iPhone上,BOOL就是bool类型.而bool类型的值有两种true(1)和false(0).任何不为0的数强转为bool类型,均转为true(即非0都为真).

另外:

- (id)performSelector:(SEL)aSelector withObject:(id)object;参数问题.
结论:performSelector的object参数只能为对象类型,其selector参数对应方法的参数也必须为对象类型,如果为基本数据类型则值不可预知,这个时候只能使用NSInvocation.

测试代码如下:

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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#import "ViewController.h"

@interface ViewController ()

@property (nonatomic, assign) BOOL val;

@property (nonatomic, assign) int num;

@end

@implementation ViewController

- (void)viewDidLoad {
[super viewDidLoad];

self.val= YES;
}

- (void)changeMyVal:(BOOL)param {
NSLog(@"%d", param);
self.val = param;
NSLog(@"%d", self.val);
}

- (void)changeNumber:(int)param {
NSLog(@"%d", param);
self.num = param;
NSLog(@"%d", self.num);
}

- (void)changeNumberObj:(NSNumber *)param {
NSLog(@"%d", param.intValue);
self.num = param.intValue;
NSLog(@"%d", self.num);
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
[super touchesBegan:touches withEvent:event];

//performSelector的object参数只能为对象类型,其selector参数对应方法的参数也必须为对象类型,如果为基本数据类型则值不可预知.
[self performSelector:@selector(changeMyVal:) withObject:@(0) afterDelay:2]; //self.val的值每次运行随机0或1
// [self performSelector:@selector(changeMyVal:) withObject:@(1) afterDelay:2]; //self.val的值每次运行随机0或1.大多数情况下是0
// [self performSelector:@selector(changeMyVal:) withObject:@(234) afterDelay:2]; //self.val的值每次运行随机0或1.

// [self performSelector:@selector(changeNumber:) withObject:@(25) afterDelay:2]; //self.num = -1985119076;(每次运行都不一样的)

// [self performSelector:@selector(changeNumberObj:) withObject:@(25) afterDelay:2]; //self.num = 25;
}


@end
阅读全文 »

今天在安装WCDB时,不管是pod install

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
-> Installing WCDB (1.0.6)
> Git download
> Git download
$ /usr/local/bin/git clone https://github.com/Tencent/wcdb.git
/var/folders/5z/1pxqzfcn77s2n7z4gmr63sdr0000gn/T/d20191216-6636-ji8u78 --template= --single-branch --depth 1 --branch v1.0.6
Cloning into '/var/folders/5z/1pxqzfcn77s2n7z4gmr63sdr0000gn/T/d20191216-6636-ji8u78'...
error: RPC failed; curl 18 transfer closed with outstanding read data remaining
fatal: The remote end hung up unexpectedly
fatal: early EOF
fatal: index-pack failed

[!] Error installing WCDB
[!] /usr/local/bin/git clone https://github.com/Tencent/wcdb.git /var/folders/5z/1pxqzfcn77s2n7z4gmr63sdr0000gn/T/d20191216-6636-ji8u78 --template= --single-branch --depth 1 --branch v1.0.6

Cloning into '/var/folders/5z/1pxqzfcn77s2n7z4gmr63sdr0000gn/T/d20191216-6636-ji8u78'...
error: RPC failed; curl 18 transfer closed with outstanding read data remaining
fatal: The remote end hung up unexpectedly
fatal: early EOF
fatal: index-pack failed

还是直接git clone,都下载不了.

1
2
3
4
5
6
7
8
9
git clone https://github.com/Tencent/wcdb.git
Cloning into 'wcdb'...
remote: Enumerating objects: 1704, done.
remote: Counting objects: 100% (1704/1704), done.
remote: Compressing objects: 100% (1192/1192), done.
error: RPC failed; curl 56 LibreSSL SSL_read: SSL_ERROR_SYSCALL, errno 54
fatal: The remote end hung up unexpectedly
fatal: early EOF
fatal: index-pack failed

从错误原因不难看出是网络的问题,应该是github被墙了。

最后解决办法:

  1. pod repo update更新仓库。

    这一步不是必须,除非你的仓库很旧,或者第二步没效果。这一步不翻墙的话同样很慢大概10kb/s的样子,但是比起后面下载源码库尤其是一些必须要翻墙才能下载的(比如libwebp),那简直小巫见大巫了。pod repo update会从github上把最新的仓库更新到本地:~/.cocoapods/repos/master,里面保存了所有第三方库的spec说明书。

  2. 从同事那里拷贝源码库(路径为~/Library/Caches/CocoaPods/Pods/Release)和源码库的说明书(路径为~/Library/Caches/CocoaPods/Pods/Specs/Release),也分别放在自己的上述两个目录下.再pod install解决.

从这里可以看出pod install都干了些啥。

参考:无法Pod install第三方库的解决办法

ps:
pod install下载下来的库的本地存储路径为
~/Library/Caches/CocoaPods,该目录包含一个搜索索引json文件,以及下载过的库的源代码和对应的Spec.
如果Podfile文件中库的版本一致则不会再从github下载,而是直接使用缓存下来的库的源码.因此如果某个库pod install很慢时,可以拷贝别人的版本一致的库到该目录下,减少等待时间.
在清理Mac磁盘存储空间时最好不要删除~/Library/Caches/CocoaPods里面的缓存,否则下次pod install会从github上重新下载源码库,这个等待时间你懂得.

阅读全文 »

一、 7日年化收益率

今天早上被一条支付宝的通知吵醒,点进去一看发现是有新的花呗账单需要偿还了,还完花呗,刷了一下余额宝,提示昨日收益0.16元,七日年化2.3280%.7日年化?怎么这么熟悉但是细细一想却又不知道到底是什么东西,这让我感到难受.看来有必要了解一下7日年化收益率究竟是什么东西?

不过一上来就讲7日年化收益率略显深奥,还是先来看一下收益率是什么?

大家都知道收益率 = 收益 / 本金.即本金在一段时间后获得的收益除以本金.收益率可以用来衡量一个理财产品的好坏.收益率越高代表到期后获得的收益也越多.

年收益率就是本金在一年以后获得的收益除以本金得到的一个比值.比如银行某个定期理财产品承诺存满一年将获得4%的年收益率.那么你存10000元,到年底的时候取出来将获得10000 x 4%=400元的总收益.

与其对应的是日收益率,即本金在一天后获得的收益除以本金.还是上面的例子,10000元存满一年获得400元收益,那么存一天获得的收益为400 / 365 ≈ 1.0959元.于是Rd = 1.0959 / 10000 = 0.010959% = 4% / 365.

因此很容易得出日收益率与年收益率存在以下关系:

Rd x 365 = Ry

Rd x 365就表示将日收益率进行年化,得到的结果Ry就是年化收益率.如果你能保证以后的日收益率都是这么多,那Ry就是年收益率了,但对于基金来说它每天的收益率是在不断变化的,所以只能称为年化收益率.

OK,前戏的部分终于讲完了,现在开始正式进入主题.

阅读全文 »

IP及端口检测

检测购买的vps IP是否被墙

检测IP是否被墙:站长工具或者使用ping命令。延迟太大的IP(400+ms)建议还是换一个。

检测端口在国内是否开放:在线检测域名或者ip的端口是否开放 。搭建完后可以再检查下配置的端口是否在国内开放。其他检测网址:IP可用性检测工具

检测端口在国外是否开放:you get signal 。这个其实没什么必要。

搭建ss

首先你需要一台服务器,以便在服务器上搭建ss。可以在vultr上购买一个vps,也可以在其他供应商购买。下面是基于vultr的vps搭建ss,用于Mac端fq.

在正式配置vps之前,务必先确保vps的IP及端口22没有被墙.否则下面的操作白搭.因为首先你得在墙内能够访问你的vps.

目前有两种方式搭建ss,一种是基于C的shadowsocks-libev(以下简称c-ss),一种是基于Python的Shadowsocks-Python(以下简称p-ss)。

基于C的shadowsocks-libev:(推荐)

阅读全文 »

OC nullability特性

众所周知,Swift语言是严格区分可选和非可选变量的.比如UIViewUIView?.而在之前的OC中却没有这个概念,二者都使用UIView*表示.由于Swift编译器无法根据UIView*判断该变量是否是可选的.因此该类型在Swift中被解释为隐式解包UIView!.而在Swift中对一个值为nil的可选变量进行强制解包时将导致崩溃.因此你必须时刻警惕UIView!变量在某处会不会被赋值为nil.这不仅带来使用上的不便,而且也影响编程体验.因此有必要让OC兼容Swift的Optional特性,方便OC的类在Swift中的使用.于是在Xcode 6.3 开始官方便给OC添加了nullability功能.

nullability 特性包含_Nullable_Nonnull这两种修饰符._Nullable表明该变量可以为nil或NULL值.而_Nonnull表明该变量不能为nil值.两个变种写法nullable,nonnull.

示例如下:

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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
#import <Foundation/Foundation.h>
#import "Person.h"

#define myCase 4

#if myCase == 1

//不使用
@interface Book : NSObject

- (instancetype)initWithName:(NSString *)name;

@property (nonatomic, copy) NSString *name;
@property (nonatomic, copy) NSString *version;
@property (nonatomic, assign) long words;
@property (nonatomic, copy) NSString *publicID;
@property (nonatomic, copy) NSString *url;
@property (nonatomic, strong) Person *author;

@end

/**
Swift接口如下:
open class Book : NSObject {


public init!(name: String!)


open var name: String!

open var version: String!

open var words: Int

open var publicID: String!

open var url: String!

open var author: Person!
}
*/

#elif myCase == 2

//推荐写法.属性都不可为nil
NS_ASSUME_NONNULL_BEGIN

@interface Book : NSObject

- (instancetype)initWithName:(NSString *)name;

@property (nonatomic, copy) NSString *name;
@property (nonatomic, copy) NSString *version;
@property (nonatomic, assign) long words;
@property (nonatomic, copy) NSString *publicID;
@property (nonatomic, copy) NSString *url;
@property (nonatomic, strong) Person *author;

@end

NS_ASSUME_NONNULL_END

#elif myCase == 3

//推荐写法,个别属性可为nil
NS_ASSUME_NONNULL_BEGIN

@interface Book : NSObject

- (instancetype)initWithName:(NSString *)name;

@property (nonatomic, copy) NSString *name;
@property (nonatomic, copy) NSString *version;
@property (nonatomic, assign) long words;
@property (nonatomic, copy, nullable) NSString *publicID;
@property (nonatomic, copy, nullable) NSString *url;
@property (nonatomic, strong) Person *author;

@end

NS_ASSUME_NONNULL_END

#elif myCase == 4

//全部自己手动定义
@interface Book : NSObject

- (nonnull instancetype)initWithName:(NSString * _Nonnull)name;

@property (nonatomic, copy) NSString * _Nonnull name;
@property (nonatomic, copy, nonnull) NSString *version;
@property (nonatomic, assign) long words;
@property (nonatomic, strong, nonnull) NSNumber *barCode;
@property (nonatomic, copy, nullable) NSString *publicID;
@property (nonatomic, copy, nullable) NSString *url;
@property (nonatomic, strong, nonnull) Person *author;
@property (nonatomic, strong, nonnull) NSMutableArray<Person *> *seeker;

@end

#endif

nullability特性对OC编码的影响

在OC中即使标明为_Nonnull,你依然可以给它一个nil值,但编译器会给出警告,仅仅是警告.因此在OC中不要对_Nonnull修饰的变量抱有一定不为nil的幻想,否则该崩还得崩.

nullability特性只是一种约定,在开发的过程中我们要遵守这一约定.如果一个变量是nonnull的,我们在init方法中一定要给它一个初始值,并且在使用过程中不要给它赋值为nil.

nullability特性对OC,Swift混编的影响

nullability特性其实主要还是为了方便OC的类在Swift中的使用.

阅读全文 »

Swift 访问控制

继承是针对类的,重写是针对类的方法的。

In Module Out Module
open 可访问,可继承,可重写 可访问,可继承,可重写
public 可访问,可继承,可重写 可访问
internal 可访问,可继承,可重写 X
fileprivate 在同一源文件里可访问,可继承,可重写 X
private 如果修饰的是类中的成员,则成员只能在自身定义里或同一源文件中的自身扩展里可访问(也就是不能被重写了),如果修饰的是类则在同一源文件里可访问,可继承 X

open只能用于修饰类和类的成员(属性,方法和下标),不能修饰协议、全局变量/常量、结构体、枚举等等(这些可以使用public修饰)。系统禁止的原因可能是因为这些类型都是值类型本身就无法继承和重写,刚好就是public的作用。

1
2
3
4
5
6
7
8
9
10
11
// Only classes and overridable class members can be declared 'open'; use 'public'

open protocol MyProtocol: AnyObject { //报错

}

open let kAPIKey = "xxx" //报错

open struct MyStruct { //报错

}

对于初始化器如果需要对外公开,则只能使用public.如果子类的初始化器和父类的初始化器签名相同则子类还需要加上override关键字.是不是感觉有点疑惑,不是说public的在其他Module只能访问吗,为啥public修饰的初始化器在其他Module还可以override?无他—龟腚.

1
2
3
4
5
6
7
open class Machine {
public var numberID: String

open init(_ numberID: String) { //这里报错:Only classes and overridable class members can be declared 'open'; use 'public'
self.numberID = numberID
}
}

唯一找到的解释如下:

Allow distinguishing between public access and public overridability

Initializers do not participate in open checking; they cannot be declared open, and there are no restrictions on providing an initializer that has the same signature as an initializer in the superclass. This is true even of required initializers. A class’s initializers provide an interface for constructing instances of that class that is logically distinct from the interface of its superclass, even when signatures happen to match and there are well-understood patterns of delegation. Constructing an object of a subclass necessarily involves running code associated with that subclass, and there is no value in arbitrarily restricting what initializers the subclass may declare.

阅读全文 »