作者: xiao, yanzi

乔布斯如何为Mac带来了优秀的字体和文字体验的?

乔布斯在大学时学过字体排版,后来的评论者也同意乔布斯为Mac带来了优秀的字体和文字体验。甚至他在斯坦福的演讲里还说“假如没有他,也许计算机排版就不那么容易”。

请问在Mac之前,计算机排版是什么情况?他到底来带了什么?

60 条回复    1970-01-01 08:00:00 +08:00
delectate
    1

delectate   2011-12-26 17:27:06 +08:00

我没觉得,说完了。
我相信乔布斯是个小人。
也就是他,别人如果没有
在那个低位,那个职位,而
像他一样无耻和卑鄙,一定会
被整个世界所唾弃!
killpanda
    2

killpanda   2011-12-26 17:28:51 +08:00

我就像提个问题,因为*近想学习一下字体和排版的知识。
delectate
    3

delectate   2011-12-26 17:30:12 +08:00

呃,我喷了,不好意思。至于说排版和字体,我了解不多。
不过按贡献来说,应该没乔布斯嘛事吧?
gnefouhs
    4

gnefouhs   2011-12-26 17:31:52 +08:00

@delectate 您在写诗吗
zxwind
    5

zxwind   2011-12-26 17:35:23 +08:00

乔布斯传刚看完这段,大概就是他提了个加字体的idea,然后工程师*次在电脑上实现了各种字体,因为mac是*批图形界面的系统,所以之前也没有电脑上的字体这个概念
killpanda
    6

killpanda   2011-12-26 17:36:19 +08:00

@zxwind 之前的字体排版用什么?机器而不是电脑?
delectate
    7

delectate   2011-12-26 17:39:29 +08:00

@zxwind ,其实,gui这东西既不是乔布斯,也不是盖茨发明的。俩人跑施乐玩了一圈,自己搞了个四不像而已。
乔布斯以前就很坏,包括不认女儿,对合伙人苛刻冷漠,欺骗供应商,敲诈等等。
如果这些问题放在普通人身上,肯定会是十恶不赦,可是谁让他是乔布斯呢?没有沃兹尼亚克,乔布斯就是一坨。
killpanda
    8

killpanda   2011-12-26 17:41:20 +08:00

@delectate 所以应验了那句话,其实一个新东西诞生后,*出名的人,总是*先推广它的人。
ywjno
    9

ywjno   2011-12-26 17:45:29 +08:00

单纯排版的话有TeX(http://zh.wikipedia.org/wiki/TeX),这是高德纳在写《计算机程序设计艺术》的时候顺便写出来的
soulhacker
    10

soulhacker   2011-12-26 18:05:06 +08:00   ❤️ 1

Jobs 在 Stanford 演讲中提到的事儿,主要是把印刷中对字体的一些高标准的处理要求引入到电脑(当时指的是 Macintosh 一代)字体的显示和打印中,比如 kerning、tracking 等等,当然不是他亲手实现的,但提出开创性的要求并有本事坚持,在很多时候是创新中*困难的一步。至于在此之前,是没有电脑能用于排版和印刷的。

V2EX 挺少碰到喷子的,喷之前还是多了解下自己在谈论的领域为好。

soulhacker
    11

soulhacker   2011-12-26 18:06:15 +08:00

更正,上一回复里说的“电脑”应该更准确的表达为“个人电脑”……
killpanda
    12

killpanda   2011-12-26 18:06:59 +08:00

@ywjno 哦 明白了。当时麦金塔出来了之后有了鼠标和图形界面,所以可以不需要用TeX这类的东西就可以比较直观的完成排版了呗?

谢!

killpanda
    13

killpanda   2011-12-26 18:07:48 +08:00

@soulhacker 谢谢。明白了!
delectate
    14

delectate   2011-12-26 18:08:43 +08:00

@soulhacker ,不好意思,让大家见笑了。
我喜欢就事论事,直来直去。看不惯乔布斯所作所为,和狂热式崇拜。再对比一下丹尼斯去世时媒体的反应,顿感世态炎凉啊。
乔布斯贡献不可否认,但是过错也不少。皮克斯也不是他要搞动画的,而是以前人家卖给他的,他还想弄pc,想战胜老东家。弄巧成拙动画倒是行了,老东家把他当功臣也请回去了。
总的来说,功过相抵。
soulhacker
    15

soulhacker   2011-12-26 18:13:45 +08:00

@killpanda 当然不是,TeX 是一种排版系统,旨在保证文档格式和板式设计跨平台的高质量和一致性,和鼠标、GUI 没有直接联系;Jobs 说的事儿更多的说的是字体显示和印刷效果如何保证接近高质量印刷品。另外,Kunth 老爷子在写 TeX 的时候意识到字体处理的重要性,于是同时写了 METAFONT,是*个用来定义矢量字体的系统(*个版本70年代末发布),Apple 在开发 Mac 的时候采用了 Adobe 的 PostScript 字体定义,可以和 METAFONT 互相转换。
soulhacker
    16

soulhacker   2011-12-26 18:16:56 +08:00

@killpanda 顺便说一句,我现在制作重要的文档还是使用 TeX,它和 Microsoft Word 这样的所见即所得编辑器非常不同,真正做到了出版级的排版,并实现了内容和样式/版式的分离。不客气地说,对于专业排版来说,「所见即所得」真是弊大于利呢。
killpanda
    17

killpanda   2011-12-26 18:21:01 +08:00

@soulhacker 明白了,*近这个问题一直困扰着我,非常感谢!!
Air_Mu
    18

Air_Mu   2011-12-26 18:27:53 +08:00

看上去在说乔布斯。其实是在很高端的嘲讽某天国王朝的伟人吧
哈哈。
Livid
    19

Livid   V2EX Moderator   2011-12-26 18:33:30 +08:00

在 Macintosh 之前,普通的个人电脑的 UI 或者 CLI 通常只有简单的固定宽度字体。

*代 Macintosh 让很多用户*次在电脑上见到了更丰富的字体显示。

lyklykkkkkkk
    20

lyklykkkkkkk   2011-12-26 18:39:55 +08:00

*个要求这么做了,也就是说*个GUI上有了美观的字体,那么之后的GUI当然也得有,这样看来,相当于是他的苹果公司提高了GUI的行业标准。

顺便,根据传记,乔布斯确实很mean,跟south park中的Eric Cartman一样。但我佩服的是他的专注能力,很难达到那种(根据传记描述来看)程度。

killpanda
    21

killpanda   2011-12-26 18:43:14 +08:00

而且爱哭!!!
zhouyang
    22

zhouyang   2011-12-26 19:12:03 +08:00

@delectate
这帖子人家在讨论:乔布斯如何为Mac带来了优秀的字体和文字体验。。
你居然能喷到”乔布斯以前就很坏,包括不认女儿,对合伙人苛刻冷漠,欺骗供应商,敲诈”
看来你还不知道这里是著名果粉社区吧
delectate
    23

delectate   2011-12-26 19:18:07 +08:00

@zhouyang 原来如此,那本人以后*不讨论任何和苹果有关的东西。
pepsin
    24

pepsin   2011-12-26 19:38:26 +08:00

@lyklykkkkkkk 这么一说还真挺像的,爱哭,善于挑唆,无事生非.整个就是瘦版Cartman 哈哈
Livid
    25

Livid   V2EX Moderator   2011-12-26 20:08:48 +08:00

@delectate 你今年多大了?
delectate
    26

delectate   2011-12-26 20:25:44 +08:00

@Livid 21,老愤青。
bhuztez
    27

bhuztez   2011-12-26 20:29:34 +08:00

@zxwind http://en.wikipedia.org/wiki/Display_PostScript
deepure
    28

deepure   2011-12-26 20:53:45 +08:00

@zhouyang 对把v2ex定义为果粉社区不敢苟同。
icefishi
    29

icefishi   2011-12-26 20:56:45 +08:00

说到哭,成年老美确实比成年中国人爱哭,但我解决为一种感情的直接表达方式。 《乔传》里说到他哭,但没说哭到啥程度,是眼泪噙在眼里还是鼻涕一把泪一把的。

我知道一个米国人,男,快到50岁了吧(详细不知道,儿子当兵战死了,推测),有一把吉它,来中国时没带来,说夸张点到了日夜思念的地步,担心国际快递不靠谱,一中国人去米国给捎来了,当他打开吉它箱的那一刻,眼泪就滴在吉它上。这个吉它有什么故事我不清楚,值多少钱也不知道,但同样的事放在中国人身上可能不会哭吧。

乔布斯也是人,他的伟大不是在他的人品上,而是在坚持自己的信念并成功了上,这样的人在全球不在少数,他能火成这样和这个信息无成本传播的时代不无关系。

个人认为没必要深度讨论乔这个人,环境不同必定结果不同。

jedicxl
    30

jedicxl   2011-12-26 21:20:07 +08:00

@delectate 看了你14楼的言论,就知道你即使看了乔布斯传也是跳着看的,以致你对事实的了解偏差到了相当的程度。
shao
    31

shao   2011-12-26 21:29:04 +08:00

我看到#26楼 淡淡一笑。
delectate
    32

delectate   2011-12-26 21:40:25 +08:00

@jedicxl 真抱歉,我没看过那本书。我看的是更客观的东西。抱歉,我又无知的顶了这帖子。
jedicxl
    33

jedicxl   2011-12-26 22:01:47 +08:00

@delectate 那么烦请给个“更客观”的出处,也好让我学习一下。
delectate
    34

delectate   2011-12-26 22:18:34 +08:00

我真后悔*初来回复这个破帖子。以后我要是再讨论苹果,自断手指一根。
客观?真相?你认为你知道的就都是真相吗?
lostab
    35

lostab   2011-12-26 22:30:55 +08:00

真是哪儿都有争吵。
立场、观点不一样时,*好的办法就是沉默。
哈哈。
wtl
    36

wtl   2011-12-26 22:31:30 +08:00

@delectate
自断手指一根……
身体发肤 受之父母
dirty
    37

dirty   2011-12-26 22:40:42 +08:00

@delectate 你在这个帖子里也没讨论过苹果,你只是在攻击乔布斯这个人罢了,何谈「再」字?
这帖子讨论的主要还是字体和个人电脑,你一上来就喷乔布斯个人无论如何也不是「就事论事」吧。
你说你看到的是更客观的东西,有人问你出处也是很正常的事,如果真有这样的资料,我也想学习一下。而「客观?真相?你认为你知道的就都是真相吗?」这句回答不知道想表达的是什么。
killpanda
    38

killpanda   2011-12-26 22:44:12 +08:00

我很看不惯非得要求一个人德艺双馨的这种行为。
codeplay
    39

codeplay   2011-12-26 22:48:34 +08:00

@delectate
Mac对于图形化界面的推动毋庸置疑,施乐不是没有推出过图形化界面的电脑产品,价格高,易用性也并不好;Macintosh的价格是大众相对可以负担的,并且创造了拖拽,窗口层叠(施乐的图形化界面里没有这些东西的,亲)这些现在都在使用的图形化界面的概念。Macintosh对于印刷行业的推动更是不能抹杀的,Adobe PhotoShop 这个软件到了 4.0才有Windows版的,为什么?了解了吗?即便褪去*款图形化个人电脑的光环,作为Macintosh的缔造者的乔布斯的功绩都是伟大的。
人无完人,如果你有兴趣读一读牛顿的传记(牛顿)或者是看看DNA发现人沃森的轶事,你会发现牛顿此人傲慢(当然他确实有傲慢的资本),而沃森言辞尖酸刻薄,但这并不妨碍他们的伟大(当然我并不认为乔布斯的成就可以和他们两位相提并论)。
jedicxl
    40

jedicxl   2011-12-26 22:55:13 +08:00

@delectate 知道你34#的话让我想起什么么?中国的民科。
“你以为你知道的就都是真想么”>“你以为你以为你知道的真相就都是真相么”>“你以为…以为你知道的真相就都是真相么”。。。。如此的引申可以无限循环下去,福尔摩斯和莫里亚蒂在火车上玩的那一套作为柯南道尔的经典败笔,原来在这里也能华丽现身啊。

另外,同意38楼的:很看不惯非得要求一个人德艺双馨的这种行为

killpanda
    41

killpanda   2011-12-26 22:58:38 +08:00

@codeplay 是的,我用过3年的ubuntu,那时候,看globalmenu+docky,和Mac OS X界面差不多,就觉得Mac也不过如此。
今年真正用了Lion,才觉得OS X的桌面体验简直不是其他操作系统可以比的,我惊叹了好久,和德芙似的,丝滑的感受啊!!
Livid
    42

Livid   V2EX Moderator   2011-12-26 22:58:45 +08:00

各位,@delectate 今年才 21 岁,我们把这个帖子留到他 31 岁的时候再和他讨论吧。或许那个时候他的想法会有些改变。
codeplay
    43

codeplay   2011-12-26 22:59:12 +08:00

@jedicxl
咱们的教育啊、文化啊就是这样啊,英雄就得伟光正,要么是好人,要么是混蛋。
lostab
    44

lostab   2011-12-26 23:05:29 +08:00

说实话,很多时候,时间、经历才是*好也是唯一的老师。但同时我也很不爽动不动就一副教育别人的态度。
@codeplay 让我想起了“老子英雄儿好汉,老子反动儿混蛋”
哈哈
codeplay
    45

codeplay   2011-12-26 23:13:54 +08:00

@killpanda
确实,Mac胜在细腻,对比Mac OSX 10.1,10.2同时代的WindowsXP,粗粗一看,XP总体其实也还Ok,但当看到那些16×16像素的图标···
likuku
    46

likuku   2011-12-26 23:33:31 +08:00

推荐这个网站,国内少有的,专业的 字体和排版 网站:

Type is Beautiful : http://www.typeisbeautiful.com/

Mr_Vangogh
    47

Mr_Vangogh   2011-12-26 23:35:56 +08:00

@delectate
“我喜欢就事论事,直来直去。”
如果你喜欢就事论事的话,在这个讨论字体排版的帖子里面说什么乔布斯的人品问题恐怕就有点矛盾了吧?直来直去挺好的。
Mr_Vangogh
    48

Mr_Vangogh   2011-12-26 23:38:18 +08:00

@Livid 感觉人年龄越大越顽固啊,更加难以认识到自身了。
Mutoo
    49

Mutoo   2011-12-26 23:38:31 +08:00

MAC下的字体是用三次方程描述的矢量图,而MS用二次方程,印刷出来效果就是差很多,
MAC胜在细节!
killpanda
    50

killpanda   2011-12-26 23:42:06 +08:00

@likuku *近就是在看这个博客,所以产生了点兴趣
likuku
    51

likuku   2011-12-26 23:44:41 +08:00

@Mr_Vangogh 追寻自我是一生的事,很难的事…
Mutoo
    52

Mutoo   2011-12-26 23:49:27 +08:00

@killpanda 关于 Mac 的字体你可以参考一下这篇文章 http://www.brainnew.com.tw/article/na2002/n_121002.htm
tomyiyun
    53

tomyiyun   2011-12-27 00:07:14 +08:00 via Android

个人感觉,苹果的产品没有切身体会很容易产生“不过如此”的感觉,这也是山寨苹果的产品泛滥的原因之一吧。
但是真正的使用和接触后,会激发出对不同方面的美的追求,这种追求的价值是之前从未意识到过的。
如若没有苹果,没有乔布斯,现在的桌面电脑、数字出版、数码设备、web体验会是怎样,也许只有在那个平行宇宙里的地球人才知道了。
BTW,V2EX给我的思维带来的影响中很重要的一个观点就是“永远不要和中二病患者辩论”。
Ricepig
    54

Ricepig   2011-12-27 00:11:33 +08:00

@Mutoo 但是苹果是为数不多的不使用子像素渲染技术的厂商

乔布斯给文字和字体带来了好的体验,有没有?有

但是“假如没有他,也许计算机排版就不那么容易”这句话呢?有点夸大。

从我个人来说,无论是Word还是Indesign都比乔布斯和苹果在这方面的贡献要大

virushuo
    55

virushuo   2011-12-27 00:43:07 +08:00

我是来顶 @livid 的42层的。
so898
    56

so898   2011-12-27 00:52:01 +08:00

我觉得JOBS说的主要是字体这方面的问题
本人参加过NDS汉化,对于字库这个非常头痛,常年就是得自己点点阵来加字,各种痛苦
话说MAC下的字体显示一直以来都非常舒服,常年被各种美化包采用哦
helsingZT
    57

helsingZT   2011-12-27 11:00:16 +08:00

@delectate 21就算是“老愤青”了么,那这里大部分人不就是万年陈尸了= =
jedicxl
    58

jedicxl   2011-12-27 14:06:49 +08:00

@Mr_Vangogh 不全是这样的。越老越顽固,是因为“认知”是需要成本的,时间、精力的大量消耗,不是任何人都愿意支付的。对于某些人,知识与见识,就好象买回家的冰箱一样,几十年不更新换代,因为他们觉得已经够用了。现在的年轻人,相信在老了以后,会比当前的老年人要开明。
bhuztez
    59

bhuztez   2011-12-27 14:30:28 +08:00

查了下Wikipedia,简单地概括一下就是,他1979年去Xerox PARC转了一圈,当场就震惊了。

现在你能在个人电脑上用到的功能,在1979年的时候,Xerox PARC已经实现了。但是Xerox高层并不觉得有多少商业价值。哪怕是在卖Xerox Star的时候,也只是认为GUI只是能帮他们多卖一些机器而已。Xerox Star实在是太超前了,一推出之后,伪科技公司都去山寨了。乔布斯从1979年开始应该就在想办法山寨了。

GUI中有一个部分是InterPress。1982年写InterPress的那几个人,离开了Xerox,成立了Adobe,他们开发重新开发了InterPress的功能,那东西就是PostScript。乔布斯找到Adobe,要求PostScript能直接用来驱动打印机。这也就有了后来的MacPublisher和LaserWriter。MacPublisher和LaserWriter算不上成功。desktop publishing这个词也是Paul Brainerd提出来的,而不是苹果的某个人。

1986年,SUN开发出了NeWS,NeWS的界面是直接用PostScript画出来的。1987年,Adobe和NeXT才一起开发出了类似的东西。

所以,对于更方便的计算机排版来说,苹果并不是不可或缺的,WYSIWYG是Xerox先发明的,PostScript是Adobe重新开发出来的,在Desktop Publishing的竞争中,苹果并不是*终的赢家,只不过当时恰好苹果家的个人电脑是比较受欢迎的,很多这方面的软件都能在苹果的电脑上跑。就算苹果不去山寨,其他厂家也会抢着山寨出来。桌面显示不正是SUN先山寨成功的嘛。乔布斯离开苹果是1985年,TrueType发布已经是1991年了。所以字体是否和乔布斯有关系真的很难说。乔布斯*大的贡献很可能就是提前两年把Xerox PARC已经实现的想法带到了苹果。虽然做的只是山寨或者说微创新,能做到这个已经很了不起了,当时谁会想到相当于是用期权去换取去PARC参观。

iOS14.5 正式版究竟什么时候能推出呀

二月上旬出的*个测试版,拖到了四月上旬还是一点消息都没有,真是让人头大

26 条回复    2021-04-08 16:57:14 +08:00
RobertLyu
    1

RobertLyu   3 天前

得等新品上架之后一周左右能出正式版。
alfchin
    2

alfchin   3 天前 via iPhone

一般还得 2-3 周*快
zhaokun
    3

zhaokun   3 天前

预测下周三官网会上架新品,第二天软件推送
guanhui07
    4

guanhui07   3 天前 via Android

这个月吧
ccming
    5

ccming   3 天前

中美贸易战后遗症,全球芯片饥荒,影响是长期的。
dicbldicbl
    6

dicbldicbl   3 天前 via iPhone

这周要出 rc 了吧。。。应该
Cavolo
    7

Cavolo   3 天前 via iPhone

新品开卖那天会推送,上架不一定就会推送
Telegram
    8

Telegram   3 天前

为啥一定要纠结这个版本
也没啥新功能更新啊,更新了个寂寞
我倒是期待 ios15 beta1
luqingliang
    9

luqingliang   3 天前

是的,就等更新了,太想要 aw 口罩解锁了
belin520
    10

belin520   3 天前 via iPhone   ❤️ 1

@ccming 芯片危机是因为疫情复工复产进度导致的

yqsas
    11

yqsas   3 天前 via iPhone

测试版已经很稳定了,日常用没遇到问题,建议更新
ccming
    12

ccming   3 天前

@belin520 不能啥都赖新冠,服装行业咋没受影响呢,轮胎行业还增长了呢
Awes0me
    13

Awes0me   3 天前

@Telegram #8

口罩解锁。。。

belin520
    14

belin520   3 天前 via iPhone

@ccming 好的
wand
    15

wand   3 天前 via iPhone

@Telegram Apple Watch 解锁 iPhone 。
edinina
    16

edinina   3 天前 via iPhone

我比较期待那个 fitness+可以投屏的更新
Telegram
    17

Telegram   3 天前 via iPhone

想用的话直接更新 beta 版本好了,到时候正式版出了,删掉描述文件再更一次就行。我现在用的就是测试版,基本没发现 bug,已经接近正式版了吧。
binfengxy
    18

binfengxy   2 天前

哪个说“口罩解锁”, 高兴了 2s…原来还要掏钱买 watch
petercui
    19

petercui   2 天前

@Telegram 支持 aw 解锁就是有些人必须更新这个版本的理由了 ………………
bubuyu
    20

bubuyu   2 天前

升级理由是支持 Watch 解锁+1,这次慢我估计跟 ATT 有关,得主要软件更新得差不多了才能上。
lxhcool
    21

lxhcool   2 天前

我已经刷回去了,因为有个游戏闪退一直
liao20
    22

liao20   8 小时 47 分钟前 via iPhone

今天已经出到 b7 了。
另外,怎么看新版本更新了啥内容?找来找去都没有
tsanie
    23

tsanie   6 小时 39 分钟前

apple watch 解锁 home 确实挺方便。

不过支付时 face id 为什么不做成“检测到戴口罩的时候立即跳过”,从而能让我立刻返回到输入密码的方式来支付?现在还要重试失败两次后才能跳过 face id,但直接关闭 face id 支付的话我不戴口罩的时候又不方便。怕是对检测戴口罩的成功率不自信

destinism
    24

destinism   2 小时 45 分钟前

@tsanie #23 求教一下,如果 app 使用 Face ID 登录,watch 能用来解锁吗?还是说只能解锁手机?
txydhr
    25

txydhr   16 分钟前 via iPhone

@destinism 只能解锁
destinism
    26

destinism   9 分钟前

@txydhr #25 谢谢。看来没必要升级了,输锁屏密码我还是能接受的…..

iPhone 选择位置权限的时候为什么不能选择拒*且下次询问呢?

6 条回复    2021-04-08 16:35:37 +08:00
yulgang
    1

yulgang   1 小时 13 分钟前

就像只有删除应用节省空间,没有单独清除应用数据节省空间一样 ,确实不方便
byicer
    2

byicer   51 分钟前 via iPhone

这个功能在 iOS13 beta4 的时候有过,请求位置时候从屏幕下往上滑就可以取消这次位置请求。
但是后来的 iOS 版本里都没有这个功能了,挺可惜。
Lullaby001
    3

Lullaby001   49 分钟前

@byicer 这里真的很烦 有些应用每次打开都请求位置,但是又不是每次都需要定位。。。结果你还必须每次答应或者完全允许,要不然需要的时候又特别麻烦。。。。无语
yohole
    4

yohole   47 分钟前

相反,我认为拒*一次之后不再弹出是*令人称道的设计,如果可以的话,你想想各种应用会有多烦人
Lullaby001
    5

Lullaby001   44 分钟前

@yohole 这两个不是非 A 即 B 的,没必要对立

iOS 开发-如何判断 iPad 是否有 home 键?

iphone 可以通过状态栏高度判断。但是 ipad 的状态栏高度,不管有无 home 键都是一样的。 有什么方法可以获取到?

11 条回复    2021-03-04 09:30:39 +08:00
gainsurier
    1

gainsurier   36 天前 via iPhone

根据设备型号判断
chinvo
    2

chinvo   36 天前 via iPhone

为什么要判断,有没有 app 都不能响应
Building
    3

Building   36 天前 via iPhone

全面屏的 iPad 状态栏不是比较高吗?
baichaohua
    4

baichaohua   36 天前

设备型号啊
yinyansheng1987
    5

yinyansheng1987   36 天前

@Building 的确是高了 4pt,刚刚靠目测感觉是一样的~
yinyansheng1987
    6

yinyansheng1987   36 天前

@chinvo 是为了底部加按钮,要空出一段安全空间
chinvo
    7

chinvo   36 天前 via iPhone   ❤️ 2

@yinyansheng1987 #5 用系统提供的 safe area 嘛
rshinich
    8

rshinich   36 天前

safe area +1
qq73666
    9

qq73666   35 天前

self.view.safeAreaInsets.bottom
1sm23
    10

1sm23   35 天前   ❤️ 1

跑个题,web 可以用 env(safe-area-inset-bottom)

shawndev
    11

shawndev   35 天前

不要用魔法值,ipad 可以分屏多个前台进程。硬编码不会解决问题,会造成问题。

iOS 开发-有大佬了解 AI 姿态识别吗?

公司要做一个运动 app 比如跳绳计数,像下面的链接这种: https://www.bilibili.com/video/BV1wU4y1Y7Mm

本人对 AI 方面毫无接触过,网上查了下资料,也是一脸懵。 目前了解到的框架有苹果自带的 Vision,但是只能在 ios14 的系统上支持体态识别。

还有 TensorFlow 和 OpenPose 两个开源框架 看了下 demo 还是无法入手( demo 都是 swift 写的,本人主 java 兼 ios,目前只会 objc?)

请问大佬要做这个功能是否需要算法基础,有没有合适的框架、教程或者可以马上上手的 demo ?

4 条回复    2021-04-08 16:57:29 +08:00
billjobs
    1

billjobs   19 分钟前

你们公司没有算法工程师的吗
yinyansheng1987
    2

yinyansheng1987   13 分钟前

@billjobs 没的,这个是否必须要会算法?
icedwatermelon
    3

icedwatermelon   10 分钟前

https://github.com/cmdbug/YOLOv5_NCNN
这个 demo 下的 Simple-pose 可能和你的需求有相关
billjobs
    4

billjobs   7 分钟前

@yinyansheng1987 又一个全干工程师

iOS 23种设计模式

设计模式主要分三个类型:创建型、结构型和行为型。 
其中创建型有: 
    一、Singleton,单例模式:保证一个类只有一个实例,并提供一个访问它的全局访问点 
    二、Abstract Factory,抽象工厂:提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们的具体类。 
    三、Factory Method,工厂方法:定义一个用于创建对象的接口,让子类决定实例化哪一个类,Factory Method使一个类的实例化延迟到了子类。 
    四、Builder,建造模式:将一个复杂对象的构建与他的表示相分离,使得同样的构建过程可以创建不同的表示。 
    五、Prototype,原型模式:用原型实例指定创建对象的种类,并且通过拷贝这些原型来创建新的对象。 
行为型有: 
    六、Iterator,迭代器模式:提供一个方法顺序访问一个聚合对象的各个元素,而又不需要暴露该对象的内部表示。 
    七、Observer,观察者模式:定义对象间一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知自动更新。 
    八、Template Method,模板方法:定义一个操作中的算法的骨架,而将一些步骤延迟到子类中,TemplateMethod使得子类可以不改变一个算法的结构即可以重定义该算法得某些特定步骤。 
    九、Command,命令模式:将一个请求封装为一个对象,从而使你可以用不同的请求对客户进行参数化,对请求排队和记录请求日志,以及支持可撤销的操作。 
    十、State,状态模式:允许对象在其内部状态改变时改变他的行为。对象看起来似乎改变了他的类。 
    十一、Strategy,策略模式:定义一系列的算法,把他们一个个封装起来,并使他们可以互相替换,本模式使得算法可以独立于使用它们的客户。 
    十二、China of Responsibility,职责链模式:使多个对象都有机会处理请求,从而避免请求的送发者和接收者之间的耦合关系 
    十三、Mediator,中介者模式:用一个中介对象封装一些列的对象交互。 
    十四、Visitor,访问者模式:表示一个作用于某对象结构中的各元素的操作,它使你可以在不改变各元素类的前提下定义作用于这个元素的新操作。 
    十五、Interpreter,解释器模式:给定一个语言,定义他的文法的一个表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。 
    十六、Memento,备忘录模式:在不破坏对象的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。 
结构型有: 
    十七、Composite,组合模式:将对象组合成树形结构以表示部分整体的关系,Composite使得用户对单个对象和组合对象的使用具有一致性。 
    十八、Facade,外观模式:为子系统中的一组接口提供一致的界面,fa?ade提供了一高层接口,这个接口使得子系统更容易使用。 
    十九、Proxy,代理模式:为其他对象提供一种代理以控制对这个对象的访问 
    二十、Adapter,适配器模式:将一类的接口转换成客户希望的另外一个接口,Adapter模式使得原本由于接口不兼容而不能一起工作那些类可以一起工作。 
    二十一、Decrator,装饰模式:动态地给一个对象增加一些额外的职责,就增加的功能来说,Decorator模式相比生成子类更加灵活。 
    二十二、Bridge,桥模式:将抽象部分与它的实现部分相分离,使他们可以独立的变化。 
    二十三、Flyweight,享元模式



<span style="word-wrap: normal; word-break: normal; line-height: 21px;"><br style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px; font-family: Arial; line-height: 26px;" />
<span style="word-wrap: normal; word-break: normal; line-height: 25px; font-family: arial, 宋体, sans-serif;"><strong><span style="word-wrap: normal; word-break: normal; line-height: 21px; color: rgb(0, 0, 153);">设计模式</span></strong>(Design Pattern),是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。</span>



<br style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px; font-family: Arial; line-height: 26px;" />
<span style="word-wrap: normal; word-break: normal; line-height: 25px; font-family: arial, 宋体, sans-serif;">使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。 设计模式于己、于他人、于系统都是多赢的,设计模式使代码编制真正工程化。设计模式是软件工程的基石,如同大厦的一块块砖石一样<span style="word-wrap: normal; word-break: normal;">使代码编制真正工程化</span>。</span>



<br style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px; font-family: Arial; line-height: 26px;" />
<span style="word-wrap: normal; word-break: normal; line-height: 25px; font-family: arial, 宋体, sans-serif;"><span style="word-wrap: normal; word-break: normal; line-height: 26px; font-family: Arial;">只有精通了设计模式,才敢说真正理解了软件工程。可以说,设计模式是每一个架构师所必备的技能之一。</span></span>作为一个面向对象设计程序员,只有精通了设计模式,才能摆脱码奴的命运,成为一个真正的软件工程师,才能完成自身价值的飞跃和设计思想的升华!



<br style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px; font-family: Arial; line-height: 26px;" />
<span style="word-wrap: normal; word-break: normal; line-height: 25px; font-family: arial, 宋体, sans-serif;">
</span>



<br style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px; font-family: Arial; line-height: 26px;" />
<span style="word-wrap: normal; word-break: normal; line-height: 25px; font-family: arial, 宋体, sans-serif;">
</span>



<br style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px; font-family: Arial; line-height: 26px;" />
<span style="word-wrap: normal; word-break: normal; line-height: 25px; font-family: arial, 宋体, sans-serif;"><strong>1、设计模式和框架</strong></span>



<br style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px; font-family: Arial; line-height: 26px;" />
<span style="word-wrap: normal; word-break: normal; line-height: 25px; font-family: arial, 宋体, sans-serif;"><span style="word-wrap: normal; word-break: normal; line-height: 24px;">  可复用面向对象软件系统现在一般划分为两大类:应用程序工具箱和</span><span style="word-wrap: normal; word-break: normal; line-height: 24px;">框架</span><span style="word-wrap: normal; word-break: normal; line-height: 24px;">(Framework),我们平时开发的具体软件都是应用程序,Java的API属于工具箱;而框架是构成一类特定软件可复用设计的一组相互协作的类,EJB(Enterprise Java Beans)是Java应用于企业计算的框架。</span></span>



<span style="word-wrap: normal; word-break: normal; line-height: 24px; font-family: arial, 宋体, sans-serif;">  框架通常定义了应用体系的整体结构类和对象的关系等等设计参数,以便于具体应用实现者能集中精力于应用本身的特定细节。框架主要记录软件应用中共同的设计决策,框架强调设计复用,因此框架设计中必然要使用设计模式。</span><span style="word-wrap: normal; word-break: normal; line-height: 24px; font-family: arial, 宋体, sans-serif;"> 
 另外,设计模式有助于对框架结构的理解,成熟的框架通常使用了多种设计模式,如果你熟悉这些设计模式,毫无疑问,你将迅速掌握框架的结构,我们一般开发
者如果突然接触EJBJ2EE等框架,会觉得特别难学,难掌握,那么转而先掌握设计模式,无疑是给了你剖析EJB或J2EE系统的一把利器。</span>

<br style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px; font-family: Arial; line-height: 26px;" />
<span style="word-wrap: normal; word-break: normal; line-height: 25px; font-family: arial, 宋体, sans-serif;">
</span>



<br style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px; font-family: Arial; line-height: 26px;" />
<span style="word-wrap: normal; word-break: normal; line-height: 25px; font-family: arial, 宋体, sans-serif;">
</span>



<br style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px; font-family: Arial; line-height: 26px;" />
<span style="word-wrap: normal; word-break: normal; line-height: 25px; font-family: arial, 宋体, sans-serif;"><strong>2、设计模式的原则</strong></span>



<br style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px; font-family: Arial; line-height: 26px;" />
<span style="word-wrap: normal; word-break: normal; line-height: 25px; font-family: arial, 宋体, sans-serif;"><span style="word-wrap: normal; word-break: normal; line-height: 24px;">近年来,大家都开始注意设计模式。那么,到底我们为什么要用设计模式呢?</span></span><span style="word-wrap: normal; word-break: normal; line-height: 24px; font-family: arial, 宋体, sans-serif;">为什么要提倡<span style="word-wrap: normal; word-break: normal;">设计模式</span>呢?</span>



<br style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px; line-height: 26px; font-family: Arial;" />
<span style="word-wrap: normal; word-break: normal; line-height: 24px; font-family: arial, 宋体, sans-serif;">根本原因是为了摆脱编程低效率,提高代码复用,增强代码健壮稳定,增加可维护性。</span>



<br style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px; line-height: 26px; font-family: Arial;" />
<span style="word-wrap: normal; word-break: normal; line-height: 24px; font-family: arial, 宋体, sans-serif;">
</span>



<br style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px; line-height: 26px; font-family: Arial;" />
<span style="word-wrap: normal; word-break: normal; line-height: 24px; font-family: arial, 宋体, sans-serif;">那怎么才能实现代码复用呢?</span>



<br style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px; font-family: Arial; line-height: 26px;" />
从
面向过程到面向对象,是软件设计诞生以来的迈出的*伟大的一步,面向对象程序设计成功解决了面向过程软件编程的低效率问题,并且彻底改变了人们的编程思
维,为软件设计揭开了新的篇章。然而,要实现面向对象设计,彻底摆脱面向过程设计思维,并不仅仅是只要使用了一门面向对象的编程语言就能够达到的。使用面
向对象设计,可以设计出优秀的软件,同样也可以设计出糟糕的软件。只有遵循一些特定的原则,才能设计出复用性高灵活性好的软件来。



<br style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px; font-family: Arial; line-height: 26px;" />
在运用面向对象的思想进行软件设计时,需要遵循的原则一共有 6 条:


</span>
  1. 单一职责原则(Single Responsibility Principle)
  2. 里氏替换原则(Liskov Substitution Principle)
  3. 依赖倒置原则(Dependence Inversion Principle)
  4. 接口隔离原则(Interface Segregation Principle)
  5. 迪米特法则(Law Of Demeter)
  6. 开闭原则(Open Close Principle)
        在软件设计的过程中,只要我们尽量遵循以上六条设计原则,设计出来的软件才会是一个优秀的软件,它必定足够健壮、足够稳定,并以*大的灵活性来迎接随时而来的需求变更等因素。 3、设计模式的四要素   设计模式使人们可以更加简单方便地复用成功的设计和体系结构。将已证实的技术表述成设计模式也会使新系统开发者更加容易理解其设计思路。

  • 模式名称(pattern name)
   一个助记名,它用一两个词来描述模式的问题、解决方案和效果。命名一个新的模式增加了我们的设计词汇。设计模式允许我们在较高的抽象层次上进行设计。基 于一个模式词汇表,我们自己以及同事之间就可以讨论模式并在编写文档时使用它们。模式名可以帮助我们思考,便于我们与其他人交流设计思想及设计结果。找到 恰当的模式名也是我们设计模式编目工作的难点之一。

  • 问题(problem)
  描述了应该在何时使用模式。它解释了设计问题和问题存在的前因后果,它可能描述了特定的设计问题,如怎样用对象表示算法等。也可能描述了导致不灵活设计的类或对象结构。有时候,问题部分会包括使用模式必须满足的一系列先决条件。

  • 解决方案(solution)
  描述了设计的组成成分,它们之间的相互关系及各自的职责和协作方式。因为模式就像一个模板,可应用于多种不同场合,所以解决方案并不描述一个特定而具体的设计或实现,而是提供设计问题的抽象描述和怎样用一个具有一般意义的元素组合(类或对象组合)来解决这个问题。

  • 效果(consequences)
  描述了模式应用的效果及使用模式应权衡的问题。尽管我们描述设计决策时,并不总提到模式效果,但它们对于评价设计选择和理解使用模式的代价及好处具有重要意义。软件效果大多关注对时间和空间的衡量,它们也表述了语言和实现问题。因为复用是面向对象设计的要素之一,所以模式效果包括它对系统的灵活性、扩充性或可移植性的影响,显式地列出这些效果对理解和评价这些模式很有帮助。 4、设计模式分类概览 《设计模式》一书,第 1 次将设计模式提升到理论高度,并将之规范化。书中一共总结了23种基本的设计模式,《设计模式》下载 这23种设计模式,几乎涵盖了面向对象设计过程中所有问题的解决方案,书中提到的23种设计模式分别是:

设计模式

(Design Pattern)

创建型

(Creational)

结构型

(Structural)

行为型

(Behavioral)

1、Abstract Factory(抽象工厂)

2、Builder(建造者)

3、Factory Method(工厂方法)

4、Prototype(原型)

5、Singleton(单态)

6、Adapter(适配器)

7、Bridge(桥模式)

8、Composite(组合)

9、Decorator(装饰)

10、Façade(外观)

11、Flyweight(享元)

12、Proxy(代理)

13、Chain of Responsibility(职责链)

14、Command(命令)

15、Interpreter(解释器)

16、Iterator(迭代器)

17、Mediator(中介)

18、Memento(备忘录)

19、Observer(观察者)

20、State(状态)

21、Strategy(策略)

22、Template Method(模板方法)

23、Visitor(访问者)

5、设计模式的设计场景 那么如此多的设计模式又是从何而来呢? 《易经》有云:“易有太*,是生两仪,两仪生四象,四象生八卦”,意思就是说世界万物皆有起源。 设计模式的起源,是面向对象程序设计思想,是面向对象设计的精髓——抽象。面向对象通过类和对象来实现抽象,实现时产生了面向对象的三个重要机制:封装、继承、多态,正是这三个机制衍生出了各种各样的设计模式。

设计模式的支持设计

目的

设计模式

可变方面

创建

(Creational)

1、Abstract Factory

2、Builder

3、Factory Method

4、Prototype

5、Singleton

产品对象家族

如何创建一个组合对象

被实例化的子类

被实例化的类

一个类的唯一实例

结构

(Structural)

6、Adapter

7、Bridge

8、Composite

9、Decorator

10、Façade

11、Flyweight

12、Proxy

对象的接口

对象的实现

一个对象的结构和组成

对象的职责,不生成子类

一个子系统的接口

对象的存储开销

如何访问一个对象,该对象的位置

行为

(Behavioral)

13、Chain of Responsibility

14、Command

15、Interpreter

16、Iterator

17、Mediator

18、Memento

19、Observer

20、State

21、Strategy

22、Template Method

23、Visitor

满足一个请求的对象

何时、怎样满足一个请求

一个语言的文法和解释

如何遍历、访问一个聚合的各元素

对象间如何交互、与谁交互

一个对象中哪些私有信息存放在该对象之外,以及在什么时候进行存储

多个对象依赖于另外一个对象,而这些对象又如何保持一致

对象的状态

算法设计

算法中的某些步骤

某些可作用于一个(组)对象上的操作,但不修改这些对象的类

6、设计模式的分类描述 设计模式,分为创建型模式、结构型模式、行为型模式

设计模式的分类描述

创建型模式

1.抽象工厂模式

为一个产品族提供了统一的创建接口。当需要这个产品族的某一系列的时候,可以从抽象工厂中选出相应的系列创建一个具体的工厂类。

2.建造者模式

将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

3.工厂方法模式

定义一个接口用于创建对象,但是让子类决定初始化哪个类。工厂方法把一个类的初始化下放到子类。

4.原型模式

用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。

5.单例模式

确保一个类只有一个实例,并提供对该实例的全局访问。

5.多例模式

确保一个类只有命名的实例,并提供对这些实例的全局访问。

对象池模式

通过回收利用对象避免获取和释放资源所需的昂贵成本。

惰性初始模式

推迟对象的创建、数据的计算等需要耗费较多资源的操作,只有在*次访问的时候才执行。

资源获取为初始化

通过绑定到合适对象的生命周期来确保资源被适当地释放。

结构型模式

6.适配器模式

将某个类的接口转换成客户端期望的另一个接口表示。适配器模式可以消除由于接口不匹配所造成的类兼容性问题。

7.桥接模式

将一个抽象与实现解耦,以便两者可以独立的变化。

8.组合模式

把多个对象组成树状结构来表示局部与整体,这样用户可以一样的对待单个对象和对象的组合。

9.装饰模式

向某个对象动态地添加更多的功能。修饰模式是除类继承外另一种扩展功能的方法。

10.外观模式

为子系统中的一组接口提供一个一致的界面, 外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。

11.享元

通过共享以便有效的支持大量小颗粒对象。

12.代理

为其他对象提供一个代理以控制对这个对象的访问。

行为型模式

13.职责链

为解除请求的发送者和接收者之间耦合,而使多个对象都有机会处理这个请求。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它。

14.命令

将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可取消的操作。

15.解释器

给定一个语言, 定义它的文法的一种表示,并定义一个解释器, 该解释器使用该表示来解释语言中的句子。

16.迭代器

提供一种方法顺序访问一个聚合对象中各个元素, 而又不需暴露该对象的内部表示。

17.中介者

包装了一系列对象相互作用的方式,使得这些对象不必相互明显作用,从而使它们可以松散偶合。当某些对象之间的作用发生改变时,不会立即影响其他的一些对象之间的作用,保证这些作用可以彼此独立的变化。

18.备忘录

备忘录对象是一个用来存储另外一个对象内部状态的快照的对象。备忘录模式的用意是在不破坏封装的条件下,将一个对象的状态捉住,并外部化,存储起来,从而可以在将来合适的时候把这个对象还原到存储起来的状态。

19.观察者模式

在对象间定义一个一对多的联系性,由此当一个对象改变了状态,所有其他相关的对象会被通知并且自动刷新。

20.状态

让一个对象在其内部状态改变的时候,其行为也随之改变。状态模式需要对每一个系统可能取得的状态创立一个状态类的子类。当系统的状态变化时,系统便改变所选的子类。

21.策略

定义一个算法的系列,将其各个分装,并且使他们有交互性。策略模式使得算法在用户使用的时候能独立的改变。

22.模板方法

模板方法模式准备一个抽象类,将部分逻辑以具体方法及具体构造子类的形式实现,然后声明一些抽象方法来迫使子类实现剩余的逻辑。不同的子类可以以不同的方式实现这些抽象方法,从而对剩余的逻辑有不同的实现。先构建一个顶级逻辑框架,而将逻辑的细节留给具体的子类去实现。

23.访问者

封装一些施加于某种数据结构元素之上的操作。一旦这些操作需要修改,接受这个操作的数据结构可以保持不变。访问者模式适用于数据结构相对未定的系统,它把数据结构和作用于结构上的操作之间的耦合解脱开,使得操作集合可以相对自由的演化。

空对象

通过提供默认对象来避免空引用。

黑板

广义的观察者在系统范围内交流信息,允许多位读者和写者。

规格

以布尔形式表示的可重绑定的商业逻辑。

在面向对象软件设计的发展过程中,除了《设计模式》一书中提到的23中设计模式之外,新的设计模式仍然不断出现。 若想更进一步了解关于面向对象设计的背景,参考接口模式、内聚、耦合。 若想更进一步了解关于面向对象编程的背景,参考继承,重载,多态,接口

iOS架构师_观察者模式

定义:
观察者模式(有时又被称为模型-视图(View)模式、源-收听者(Listener)模式或从属者模式),一个目标物件管理所有相依于它的观察者物件,并且在它本身的状态改变时主动发出通知。这通常透过呼叫各观察者所提供的方法来实现。此种模式通常被用来实现事件处理系统。

%title插图%num

%title插图%num

示例代码:自己实现观察者模式

创建Protocol类型的接口文件SubProtocol协议类

SubProtocol.h

1 #import <Foundation/Foundation.h>
2
3 @protocol SubProtocol <NSObject>
4
5 //用户的信息和从某一个刊物接收的信息
6 – (void)subMessage:(id)message withSubNumber:(NSString *)withSubNumber;
7 @end

创建观察中心SubCenter类
SubCenter.h

1 #import <Foundation/Foundation.h>
2 #import “SubProtocol.h”
3
4 @interface SubCenter : NSObject
5 // 创建书刊订阅号
6 + (void)creatNumber:(NSString *)subNumber;
7
8 // 移除订阅号
9 + (void)removeNumber:(NSString *)subNumber;
10
11 // 添加用户
12 + (void)addUser:(id <SubProtocol>)user wihtNumber:(NSString *)userNumber;
13
14 // 移除用户
15 + (void)removeUser:(id <SubProtocol>)user withNumber:(NSString *)userNumber;
16
17 // 发送消息
18 + (void)sendMessage:(id)message withSubNumber:(NSString *)SubNumber;
19
20 @end

SubCenter.m

1 //
2 //  SubCenter.m
3 //  观察者模式
4 //
5 //  Created by James on 2017/12/9.
6 //  Copyright © 2017年 TZ. All rights reserved.
7
8
9 #import “SubCenter.h”
10
11
12 static NSMutableDictionary *bookCenter = nil;
13 @implementation SubCenter
14
15 //单例
16 + (void)initialize {
17     if (self == [SubCenter class]) {
18         bookCenter = [NSMutableDictionary dictionary];
19     }
20 }
21
22 // 创建书刊订阅号
23 + (void)creatNumber:(NSString *)subNumber {
24     //  NSHashTable 就是一个集合,但是它是弱引用的.
25     NSHashTable *hashTable = [self existNumber:subNumber];
26     if (hashTable == nil) {
27         hashTable = [NSHashTable weakObjectsHashTable];
28         [bookCenter setObject:hashTable forKey:subNumber];
29     }
30 }
31
32 // 移除订阅号
33 + (void)removeNumber:(NSString *)subNumber {
34     NSHashTable *hashTable = [self existNumber:subNumber];
35     if (hashTable) {
36         [bookCenter removeObjectForKey:subNumber];
37     }
38 }
39
40 // 添加用户
41 + (void)addUser:(id <SubProtocol>)user wihtNumber:(NSString *)userNumber {
42     NSHashTable *hashTable = [self existNumber:userNumber];
43     [hashTable addObject:user];
44 }
45
46 // 移除用户
47 + (void)removeUser:(id <SubProtocol>)user withNumber:(NSString *)userNumber {
48     NSHashTable *hashTable = [self existNumber:userNumber];
49     [hashTable removeObject:user];
50 }
51
52 // 发送消息
53 + (void)sendMessage:(id)message withSubNumber:(NSString *)SubNumber {
54     NSHashTable *hashTable = [self existNumber:SubNumber];
55     if (hashTable) {
56         //构造器
57         NSEnumerator *enumerato = [hashTable objectEnumerator];
58         id <SubProtocol> object = nil;
59
60         while (object = [enumerato nextObject]) {
61             if ([object respondsToSelector:@selector(subMessage:withSubNumber:)]) {
62                 [object subMessage:message withSubNumber:SubNumber];
63             }
64         }
65
66     }
67 }
68
69 #pragma mark – 私有方法
70 // 实现了代理方法
71 + (NSHashTable *)existNumber:(NSString *)subStringNumber {
72     return [bookCenter objectForKey:subStringNumber];
73 }
74
75 @end

ViewController调用

1 #import “ViewController.h”
2 #import “SubCenter.h”
3
4
5 static NSString *SCIENCE = @”SCIENCE”;
6 @interface ViewController () <SubProtocol>
7
8 @end
9
10 @implementation ViewController
11
12 – (void)viewDidLoad {
13     [super viewDidLoad];
14     // Do any additional setup after loading the view, typically from a nib.
15     // 创建订阅
16     [SubCenter creatNumber:SCIENCE];
17
18     // 添加订阅
19     [SubCenter addUser:self wihtNumber:SCIENCE];
20
21     // 发送消息
22     [SubCenter sendMessage:@”11″ withSubNumber:SCIENCE];
23 }
24
25 – (void)subMessage:(id)message withSubNumber:(NSString *)withSubNumber {
26     NSLog(@”—-%@—-%@”,message, withSubNumber);
27 }
28
29
30 @end

iOS架构师_策略模式

什么是策略设计模式?
概念:定义一系列的算法,并且将每个算法封装起来,算法之间还可以互相替换。这种设计模式称为策略模式。

为了解决if-else和switch-case的问题,在实际开发中,较长的if-else会使代码阅读困难。

%title插图%num

代码示例:下面是一个简单的if-else代码

Demo1

1 #import “ViewController.h”
2 typedef NS_ENUM(NSInteger) {
3     Count01,
4     Count02,
5     Count03,
6     Count04,
7     Count05,
8 }EnumCount;
9
10 @interface ViewController ()
11
12 @end
13
14 @implementation ViewController
15
16 – (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
17     EnumCount count = Count04;//声明枚举,并给了一个固定的输入值
18     if (count == 1) {
19         NSLog(@”count = %lu”,count);
20
21     } else if (count == 2) {
22         NSLog(@”count = %lu”,count);
23
24     }else if (count == 3) {
25         NSLog(@”count = %lu”,count);
26
27     }else if (count == 4) {
28         NSLog(@”count = %lu”,count);
29
30     } else {
31         NSLog(@”count = %lu”,count);
32     }
33 }
34 @end

我们使用正常的代码抽离方式对其优化分离。

创建一个NSObject的类,Logic

Logic.h

1 #import <Foundation/Foundation.h>
2
3 typedef NS_ENUM(NSInteger) {
4     Count01,
5     Count02,
6     Count03,
7     Count04,
8     Count05,
9 }EnumCount;
10
11 @interface Logic : NSObject
12
13 + (NSUInteger)logic:(NSUInteger)integer;
14
15 @end

Logic.m

1 #import “Logic.h”
2
3 @implementation Logic
4 + (NSUInteger)logic:(NSUInteger)integer {
5     NSUInteger num;
6     if (integer == 1) {
7         num = 1;
8
9     } else if (integer == 2) {
10         num = 2;
11
12     }else if (integer == 3) {
13         num = 3;
14
15     }else if (integer == 4) {
16         num = 4;
17
18     } else {
19         num = 0;
20     }
21     return num;
22 }
23 @end

那么修改ViewController如下

1 #import “ViewController.h”
2 #import “Logic.h”
3
4 @interface ViewController ()
5
6 @end
7
8 @implementation ViewController
9
10 – (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
11     EnumCount count = Count04;
12     NSUInteger integer = [Logic logic:count];
13     NSLog(@”integer = %lu”, integer);
14 }
15 @end

那么如何使用策略模式呢?

新建继承自NSObject 的 BaseType类

BaseType.h文件

1 #import <Foundation/Foundation.h>
2
3 typedef NS_ENUM(NSInteger) {
4     Count01,
5     Count02,
6     Count03,
7     Count04,
8     Count05,
9 }EnumCount;
10
11 @interface BaseType : NSObject
12 //返回计数结果
13 +(NSUInteger)backCountResult;
14 @end

BaseType.m

1 #import “BaseType.h”
2
3 @implementation BaseType
4 //抽象方法
5 +(NSUInteger)backCountResult {
6     //编写代码
7     return nil;
8 }
9 @end

创建继承自BaseType的子类CountTypes01

CountTypes01.h

1 #import “BaseType.h”
2
3 @interface CountTypes01 : BaseType
4
5 @end

CountTypes01.m

1 #import “CountTypes01.h”
2
3 @implementation CountTypes01
4
5 + (NSUInteger)backCountResult {
6     // 编写代码
7     return 10;
8 }
9 @end

那么修改ViewController如下

1 #import “ViewController.h”
2 #import “CountTypes01.h”
3
4 @interface ViewController ()
5
6 @end
7
8 @implementation ViewController
9
10 – (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
11     NSUInteger integer = [CountTypes01 backCountResult];
12
13     NSLog(@”integer = %lu”, integer);
14
15 }
16 @end

优缺点
策略模式的优点是能解决代码的耦合度,但是它是有牺牲的,为了解决代码耦合度,我们需要创建更多的类。

%title插图%num

Demo2
需求:验证两个textField的输入条件

%title插图%num

初始代码:
ViewController.m

1 #import “ViewController.h”
2
3 @interface ViewController () <UITextFieldDelegate>
4 @property (weak, nonatomic) IBOutlet UITextField *letterInput; /**< 字母输入 */
5 @property (weak, nonatomic) IBOutlet UITextField *numberInput; /**< 数字输入 */
6 @end
7
8 @implementation ViewController
9
10 – (void)viewDidLoad {
11     [super viewDidLoad];
12     // Do any additional setup after loading the view, typically from a nib.
13     self.letterInput.delegate = self;
14     self.numberInput.delegate = self;
15 }
16
17 – (IBAction)btnClick:(id)sender {
18     [self.view endEditing:YES];
19 }
20
21 #pragma mark – UITextFieldDelegate
22 – (void)textFieldDidEndEditing:(UITextField *)textField {
23     if (textField == self.letterInput) {
24         // 验证它的输入值, 确保它输入的是字母
25         NSString *outputLatter = [self validateLatterInput:textField];
26         if (outputLatter) {
27             NSLog(@”—%@”,outputLatter);
28         }else {
29             NSLog(@”—输入是空的”);
30         }
31
32     } else if (textField == self.numberInput) {
33        // 验证它的输入值, 确保它输入的是数字
34         NSString *outputNumber = [self validateNumberInput:textField];
35         if (outputNumber) {
36             NSLog(@”—%@”,outputNumber);
37         }else {
38             NSLog(@”—输入是空的”);
39         }
40     }
41 }
42
43 #pragma mark – 验证输入
44 – (NSString *)validateLatterInput:(UITextField *)textField {
45     if (textField.text.length == 0) {
46         return nil;
47     }
48
49     // ^[a-zA-Z]*$ 从开头(^)到结尾($), 有效字符集([a-zA-Z])或者更多(*)个字符
50     NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@”^[a-zA-Z]*$” options:NSRegularExpressionAnchorsMatchLines error:nil];
51     //NSMatchingAnchored 从开始处就进行*限匹配
52     NSUInteger numberOfMatches = [regex numberOfMatchesInString:[textField text] options:NSMatchingAnchored range:NSMakeRange(0, [[textField text] length])];
53
54     NSString *outLatter = nil;
55     // 进行判断,匹配不符合表示0的话, 就走下面的逻辑
56     if (numberOfMatches == 0) {
57         outLatter = @”不全是字母, 输入有误,请重新输入”;
58     } else {
59         outLatter = @”输入正确,全部是字母”;
60     }
61
62     return outLatter;
63 }
64
65 – (NSString *)validateNumberInput:(UITextField *)textField {
66     if (textField.text.length == 0) {
67         return nil;
68     }
69
70     // ^[a-zA-Z]*$ 从开头(^)到结尾($), 有效字符集([a-zA-Z])或者更多(*)个字符
71     NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@”^[0-9]*$” options:NSRegularExpressionAnchorsMatchLines error:nil];
72
73     NSUInteger numberOfMatches = [regex numberOfMatchesInString:[textField text] options:NSMatchingAnchored range:NSMakeRange(0, [[textField text] length])];
74
75     NSString *outLatter = nil;
76     // 进行判断,匹配不符合表示0的话, 就走下面的逻辑
77     if (numberOfMatches == 0) {
78         outLatter = @”不全是数字, 输入有误,请重新输入”;
79     } else {
80         outLatter = @”输入正确,全部是数字”;
81     }
82
83     return outLatter;
84
85 }
86
87
88 @end

我们知道,所有的设计模式都是为了代码解耦合所使用的,代价肯定是需要创建其他的类,将代码分离。

那么我们如何使用策略模式来优化代码呢?

首先我们创建一个继承自NSObject的抽象类:InputTextFieldValidate

InputTextFieldValidate.h

1 #import “InputTextFieldValidate.h”
2
3 @implementation InputTextFieldValidate
4 – (BOOL)validateInputTextField:(UITextField *)textField {
5     return NO;
6 }
7 @end

InputTextFieldValidate.m

1 #import “LatterTextFieldValidate.h”
2
3 @implementation LatterTextFieldValidate
4
5 – (BOOL)validateInputTextField:(UITextField *)textField {
6     if (textField.text.length == 0) {
7         self.attributeInputStr = @”字母不能是空的”;
8         return nil;
9     }
10
11     // ^[a-zA-Z]*$ 从开头(^)到结尾($), 有效字符集([a-zA-Z])或者更多(*)个字符
12     NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@”^[a-zA-Z]*$” options:NSRegularExpressionAnchorsMatchLines error:nil];
13
14     NSUInteger numberOfMatches = [regex numberOfMatchesInString:[textField text] options:NSMatchingAnchored range:NSMakeRange(0, [[textField text] length])];
15
16 //    NSString *outLatter = nil;
17     // 进行判断,匹配不符合表示0的话, 就走下面的逻辑
18     if (numberOfMatches == 0) {
19         self.attributeInputStr = @”不全是字母, 输入有误,请重新输入”;
20     } else {
21         self.attributeInputStr = @”输入正取,全部是字母”;
22     }
23
24     return self.attributeInputStr == nil ? YES : NO;
25 }
26 @end

 

然后创建一个继承自UITextField的类:CustomTextField(自定义的TextField)

CustomTextField.h

1 #import <UIKit/UIKit.h>
2 #import “InputTextFieldValidate.h”
3
4 @interface CustomTextField : UITextField
5
6 // 抽象的策略
7 @property (nonatomic, strong) InputTextFieldValidate *inputValidate;
8
9 // 验证是否符合要求
10 – (BOOL)validate;
11 @end

CustomTextField.m

1 #import <UIKit/UIKit.h>
2 #import “InputTextFieldValidate.h”
3
4 @interface CustomTextField : UITextField
5
6 // 抽象的策略
7 @property (nonatomic, strong) InputTextFieldValidate *inputValidate;
8
9 // 验证是否符合要求
10 – (BOOL)validate;
11 @end

ViewController.m就简洁多了,修改如下:

1 #import <UIKit/UIKit.h>
2 #import “InputTextFieldValidate.h”
3
4 @interface CustomTextField : UITextField
5
6 // 抽象的策略
7 @property (nonatomic, strong) InputTextFieldValidate *inputValidate;
8
9 // 验证是否符合要求
10 – (BOOL)validate;
11 @end

ViewController.m就简洁多了,修改如下:

1 #import “ViewController.h”
2 #import “CustomTextField.h”
3 #import “LatterTextFieldValidate.h”
4 #import “NumberTextFieldValidate.h”
5
6
7 @interface ViewController () <UITextFieldDelegate>
8 @property (weak, nonatomic) IBOutlet CustomTextField *letterInput; /**< 字母输入 */
9 @property (weak, nonatomic) IBOutlet CustomTextField *numberInput; /**< 数字输入 */
10 @end
11
12 @implementation ViewController
13
14 – (void)viewDidLoad {
15     [super viewDidLoad];
16     // Do any additional setup after loading the view, typically from a nib.
17     self.letterInput.delegate = self;
18     self.numberInput.delegate = self;
19
20     // 初始化
21     self.letterInput.inputValidate = [LatterTextFieldValidate new];
22     self.numberInput.inputValidate = [NumberTextFieldValidate new];
23
24 }
25
26 – (IBAction)btnClick:(id)sender {
27     [self.view endEditing:YES];
28 }
29
30 #pragma mark – UITextFieldDelegate
31 – (void)textFieldDidEndEditing:(UITextField *)textField {
32     if ([textField isKindOfClass:[CustomTextField class]]) {
33         [(CustomTextField *)textField validate];
34     }
35 }
36
37 @end

优点:控制器代码简洁,分离代码复用性高,逻辑清晰,方便拓展。

用Mac自带的airport抓包以及用aircrack-ng进行Wi-Fi密码破解

用Mac自带的airport抓包以及用aircrack-ng进行Wi-Fi密码破解

电脑配置
MacAir 2015年款
版本:10.15.2
内存:8g
Mac上需要Xcode,提前安装Xcode会为我们解决很多不必要的麻烦,如果提示版本低无法安装,直接在App store中搜索macOS Mojave(这个版本是14)下载安装即可。

声明:本文章只供学习使用,请勿用做非法用途
本人菜鸟,看了很多文章,为大家总结一下,欢迎指教,只为和大家学习交流。

了解一下Mac自带的Wi-Fi工具airport
在终端中输入
sudo /System/Library/PrivateFrameworks/Apple80211.framework/Versions/A/Resources/airport -s
1

%title插图%num

此命令主要为了获取ssid bssid ch等信息。

如果你不想每次启用airport时输入一长串的命令 就定义一个alisa吧.
vim ~/.bash_profile
1
将下面这段话插入进去

alias airport=”/System/Library/PrivateFrameworks/Apple80211.framework/Versions/A/Resources/airport -s”
1

%title插图%num
保存并退出vim,如果你不了解vim的使用,可以借阅以下链接
vi/vim的使用方法
为了让我们的alias快速生效,我们还需要手动更新一下,在终端中输入以下代码即可生效
source ~/.bashrc
1
再之后 你不需要输入一长串的命令,直接输入airport就可以得到周围Wi-Fi的信息为下一步的抓包准备了。

为你的Mac安装aircrack-ng
在这之前我搜索了很多文章都推荐用Macports来安装aircrack-ng但是我尝试多次始终报错,就采取了homebrew来安装aircrack-ng如果你和我一样报错,那就用brew来安装吧
Homebrew的安装下载以下文件到你的Mac电脑中,
连接:链接:https://pan.baidu.com/s/1eRqswzRXeARginnEPtsK8Q
提取码:rxit

在终端中运行以下命令
ruby /Users/你自己的用户名/Downloads/brew_install.rb
1
我已经安装过了就不再安装了,接下来你可能需要等待10分钟左右,判断你的Homebrew是否安装完成输入brew -v即可,输入后他将显示版本号等信息,说明你安装成功了。

安装aircrack-ng
上面已经安装好了Homebrew直接运行以下命令即可安装aircrack-ng,接下来就让我们的brew来为我们安装aircrack-ng吧
brew install aircrack-ng
1
接下来开始等待brew来为我们安装吧。

好了,一切准备就绪,开工!

终端中输入airport(前面已经定义了alias了)
airport
1

%title插图%num

看ssid列找到你想要的破解的Wi-Fi名称,并记录ch信道下的数字。

开始用你的网卡进行监听并获取握手包,假如我们想要监听Wi-Fi他的信道是40,就输入以下命令 (en0是你的网卡名称,可通过ifconfig获取这里不再叙述了,一般都是en0)
airport en0 sniff 40
1
此时我们需要等待抓包,当然他可能会提示你
Could not open device en0 (en0: You don’t have permission to capture on that device ((cannot open BPF device) /dev/bpf0: Permission denied)).
处理方法:

cd /dev
ls -la | grep bp

whoami //查看当前的用户名
sudo chown 上面看到的用户名:admin bp*

权限问题都可用此方法处理,至此,处理了网卡权限不足问题,回归到前面,继续输入抓包命令
airport en0 sniff 40

开始监听的时候你的Wi-Fi图标会变成一个眼睛以及终端的提醒
Capturing 802.11 frames on en0.

%title插图%num

通常我们监听的时间会持续5到十分钟,结束监听的命令
control+c
结束后,会提醒我们**.cap**文件保存的位置,

%title插图%num
6、打开访达(finder)按shift+command+g出现搜索框,键入/tmp到达文件存放的位置

%title插图%num

 

进入后我们会看到刚才的那个.cap文件

%title插图%num

好了 我们已经找到这个文件了,输入下面的代码,看是否含有密码信息
sudo aircrack-ng /tmp/airportSniffTRT4xj.cap
1
WPA (0 handshake)里面的0代表失败,1代表成功,我们要找到带有1的哪一行,可以直接搜索command+f

%title插图%num

我们可以找到第1562行抓取成功,好了接下来就让我们开始尝试米密码破解吧

尝试Wi-Fi密码破解
先进入我们密码文本存放的位置,假如在你的桌面上有个存放密码的文件夹WiFi,那就输入以下命令
cd ~/Desktop/wifi
1
再使用aircrack-ng进行破解,输入以下命令
sudo aircrack-ng -w 123.txt /tmp/*.cap
1

在这里输入刚才有**WPA (1 handshake)**这一行,我的是1562行,开始尝试破解。

%title插图%num

可以看到很快就破解了这个弱密码1234567890,当然这是在运气很好的情况下,如果你的字典很弱,你需要收集很多字典来为你的渗透做准备

react native ios打包到真机

每当在模拟器上完成了开发,都想到真机上秀秀,正好前段时候买了一个mac,哈哈有机会了。

%title插图%num

前篇文章以android为例,这里就以ios为例,讲一下打包到iphone真机的流程。

 

一、前置

1.首先你得有一部iphone

2.首先react native的环境要正确安装,还未完成这一步的,请到官网或中文站查看具体流程

3.xcode等环境安装完毕

4.rn应用能在模拟器中跑起来,至少不要有致命错误吧

 

二、生成jsbundle

1.进入rn项目的ios工程文件夹,找到和rn项目同名的文件件,打开AppDelegate.m文件,将这一行注释掉(为了方便真机和模拟器间的切换,尽量注释):

jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@”index.ios” fallbackResource:nil];
新加一行:

jsCodeLocation = [[NSBundle mainBundle] URLForResource:@”index.ios” withExtension:@”jsbundle”];
如果需要切换回模拟器调试,只需要将新加这行注释掉,并恢复原代码即可。

新加这行代码大概意思就是告诉native rn代码的入口,我们会在下一步生成这个jsbundle。

 

2.打开终端,进入你的rn工程,在根目录下执行bundle命令:

react-native bundle –entry-file ./index.ios.js –bundle-output ./ios/bundle/index.ios.jsbundle –platform ios –assets-dest ./ios/bundle –dev false
参数说明:

–entry-file 指定入口文件 因为要打包ios平台,所以指定为rn项目的index.ios.js作为入口

–bundle-output 指定输出的jsbundle文件路径和文件名 指定到rn项目的ios工程文件夹下,记得一定要先创建bundle文件夹,不然终端会报文件夹找不到的错误

–platform 指定平台类型

–assets-dest 指定资源文件夹路径 assets文件夹的路径,包含图片、node模块等资源

–dev 是否为开发模式 如果设置为false,不会产生警告,并且bundle会被压缩

还有其他命令,比如:transformer、prepack、bundle-encoding等,可以到官网查看具体介绍。

 

bundle生成完成后,终端会有类似提示:

%title插图%num

 

3.用xcode Open another project打开rn项目的ios工程文件夹:

%title插图%num

%title插图%num

 

将之前打包好的jsbundle和assets拖入rndemo这个文件夹下面,注意一定要选择 Create folder references:

%title插图%num

三、配置网络访问白名单

应用中如果有网络请求,这一步必不可少,要不然会出现网络请求失败的错误提示。

1.打开Info.plist:

%title插图%num

2.在App Transport Security Settings下添加key:Exception Domains,类型为Dictionary。

3.在Exception Domains下添加你的应用可能会访问到的域名,key为域名,类型为Dictionary。需要注意的是:

iOS 9及以上版本,非HTTS的网络是被禁止的,当然我们也可以把NSAllowsArbitraryLoads设置为YES禁用ATS。不过iOS 10从2017年1月1日起苹果不允许我们通过这个方法跳过ATS,也就是说强制我们用HTTPS,如果不这样的话提交App可能会被拒*。但是我们可以通过NSExceptionDomains来针对特定的域名开放HTTP可以容易通过审核。每个域名都需要三个属性,key分别为:

NSIncludesSubdomains 是否包含子域 设置为true

NSExceptionRequiresForwardSecrecy 指定域名是否支持Forward Secrecy 设置为false

NSExceptionAllowsInsecureHTTPLoads 是否能使用http协议,默认是只能请求https的 设置为true

类型都为Boolean。

比如这里,我增加了api.douban.com这个白名单域,因为它本身就是走的https协议,那三个子属性我便没再做配置。应用需要访问的域都可以加到这里。

 

四、设置应用图标和闪屏图片(启动图)

在xcode中点击Images.xcassets文件夹,这是保存应用图标和闪屏等的文件夹:

%title插图%num

可以看到应用图标是按照尺寸分类了的,具体每个类型的图片大小要求可以自行查找资料,一定要保证同样的分辨率,而且不需要是圆角,否则在编译的时候会有警告提示。

闪屏的话,可以右键添加LaunchImage,也是同样的按尺寸和方向分类的,只需要拖入对应的图片即可。

图标和启动图我都是胡乱弄的,要弄齐所有还是很麻烦。

 

五、连接iphone到电脑,并让它们处于wifi的同一网段

1.连接好iphone以后,将设备选择为你的iphone,并点击xcode左上方的build按钮,就可以执行构建了:

%title插图%num

2.构建完成以后,xcode会有个没法启动应用的提示。原因是你的手机没有信任这个程序,在手机设置中:通用->设备管理->开发者应用 中信任这个应用,然后点击应用图标即可启动应用了。

 

构建中途可能会有错误或者警告提示,可根据具体的提示查找解决办法。

我遇到过两个错误:

1.app id不唯一,在这里可以重新设置:

%title插图%num

2.签名那里没有指定一个team:

%title插图%num

在这里可以按照提示一步一步设置

 

还需要注意的是部署的目标要和iphone系统版本一致:

%title插图%num

对于native小白来说,这些的确很陌生,哈哈

*后,祝你玩的愉快

友情链接: SITEMAP | 旋风加速器官网 | 旋风软件中心 | textarea | 黑洞加速器 | jiaohess | 老王加速器 | 烧饼哥加速器 | 小蓝鸟 | tiktok加速器 | 旋风加速度器 | 旋风加速 | quickq加速器 | 飞驰加速器 | 飞鸟加速器 | 狗急加速器 | hammer加速器 | trafficace | 原子加速器 | 葫芦加速器 | 麦旋风 | 油管加速器 | anycastly | INS加速器 | INS加速器免费版 | 免费vqn加速外网 | 旋风加速器 | 快橙加速器 | 啊哈加速器 | 迷雾通 | 优途加速器 | 海外播 | 坚果加速器 | 海外vqn加速 | 蘑菇加速器 | 毛豆加速器 | 接码平台 | 接码S | 西柚加速器 | 快柠檬加速器 | 黑洞加速 | falemon | 快橙加速器 | anycast加速器 | ibaidu | moneytreeblog | 坚果加速器 | 派币加速器 | 飞鸟加速器 | 毛豆APP | PIKPAK | 安卓vqn免费 | 一元机场加速器 | 一元机场 | 老王加速器 | 黑洞加速器 | 白石山 | 小牛加速器 | 黑洞加速 | 迷雾通官网 | 迷雾通 | 迷雾通加速器 | 十大免费加速神器 | 猎豹加速器 | 蚂蚁加速器 | 坚果加速器 | 黑洞加速 | 银河加速器 | 猎豹加速器 | 海鸥加速器 | 芒果加速器 | 小牛加速器 | 极光加速器 | 黑洞加速 | movabletype中文网 | 猎豹加速器官网 | 烧饼哥加速器官网 | 旋风加速器度器 | 哔咔漫画 | PicACG | 雷霆加速