Article by 付军

FKRealGroup - Xcode文件夹创建删除增强插件

What is this? FKRealGroup是一个增强Xcode创建、删除文件夹的插件。FKRealGroup会在编辑菜单中添加"New Real Group"和"Delete Real Group"两个选项。 新建文件夹 我们知道,Xcode本身的"New Group"选项只会创建一个虚拟文件夹,并不会在本地磁盘创建真实文件夹。一般来说,我们会右击->Show in Finder->在文件目录创建文件夹->右击->Add Files to "xxx"…,非常繁琐。 FKRealGroup可以解决这个问题。"New Real Group"选项会在相应磁盘目录创建一个真实的文件夹,创建逻辑如下: 目录中无,本地有的文件夹,直接警告,不加入。 目录中有,本地有的文件夹,直接警告,不创建。 目录中无,本地无的文件夹,直接创建。…

FKConsole - Xcode控制台中文显示调整插件

What is this? FKConsole是一个用于在Xcode控制台显示中文的插件。 很多情况下,在程序中打印中文的时候: NSLog(@"%@", (@[@"测试", @"好的"]).description); 在控制台的输出往往是: ( "\U6d4b\U8bd5", "\U597d\U7684" ) 这不是我们想要的结果。 FKConsole就是为此而生的。FKConsole并不会影响你的程序,FKConsole只会对Xcode控制台内的文字进行处理,所以请放心使用。 开启FKConsole之后,控制台的输出会变成这样: ( "测试啊", "好的" ) How to install it? 推荐使用Alcatraz。 你也可以clone整个工程,然后编译,插件会自动安装到~/Library/Application Support/Developer/Shared/Xcode/Plug-ins这个目录上。 一定要选Load Bundle,Skip的话,插件是无法生效的。 How to use it? 点击Xcode的Plugins菜单,在FKConsole选项上可以进行勾选和取消勾选。 Xcode…

Xcode7 插件开发:从开发到pull到Alcatraz

开发 Xcode很强大,但是有些封闭,官方并没有提供Xcode插件开发的文档。喵神的教程比较全,也比较适合入门。本文的教程只是作为我在开发FKConsole的过程中的总结,并不会很全面。 FKConsole是我开发的一个用于在Xcode控制台显示中文的插件,很小,很简单。这个插件开发的初衷是因为一个朋友有这种需求,而又没有找到相应的插件。如果不使用插件,就要在工程中嵌入文件,他并不乐意。所以FKConsole在设计上只会去修改Xcode控制台内的文字显示,绝不会去修改你的文件,这点大家可以放心。 模板 因为现在已经有很多人做Xcode插件开发了,所以插件模板这种东西也就应运而生了。 Xcode-Plugin-Template是一个Xcode插件开发的基本模板,可以使用Alcatraz直接安装,支持Xcode 6+。 安装完成之后,在创建工程的时候,会出现一个Xcode Plugin的选项,这个就是Xcode的插件工程模板。 模板会生成NSObject_Extension和你的工程名称一样的两个文件(.m)。 NSObject_Extension.m中的+ (void)pluginDidLoad:(NSBundle *)plugin方法也是整个插件的入口。 一般来说,我们希望我们的插件是存活于整个Xcode的生命周期的,所以一般是一个单例,这个在另一个文件中会有体现。 添加按钮 这篇博文是记录FKConsole开发过程的,自然以此举例。 Xcode启动之后,会发出NSApplicationDidFinishLaunchingNotification的通知,…

2015年书单

今年一直在途牛,开发了途牛NB-App和去途-App两个项目。NB-App是从去年我来了之后开始开发的,从去年的9月底的1.0.0版本,一直到现在的3.1.0版本,明年也会继续升级。去途-App是给途牛全职、兼职的导游使用的一个管理类的App,在12月中旬开发,于2016年1月上线。 本来在开发去途App的时候是想使用Swift2.0开发的,后来由于一些原因,还是依然采用objc开发了,但是,我们尝试引入了ReactiveCocoa,来比较好的满足MVVM模式的开发。当然,RAC也带入了很多函数式的特性,非常方便,我是电子专业出生,没见过这种方式,感到非常新奇。因为我一直以来使用的都是偏向于命令式的编程语言,像objc、Python(有一定的函数式编程能力)这种,我在使用函数式的时候,依然只是把它当做一个补充的语法糖,并不会使用函数式的方式去思考问题,写出来的东西不伦不类,并没有掌握函数式编程的真正精髓。 所以我去学习了一点Haskell,我想从正统的函数式编程语言上,去学习如何用函数式的方式思考问题,这本书会体现在我的书单上。 Haskell比较难学,起码比我学objc的时候难,总有一种看的时候有点会,但是解决问题的时候,又感觉有的时候无从下手,又想回到命令式的困顿。 iOS 首先,我还是介绍一下今年看的iOS相关的书籍。…

Article in: iOS

Objective-C runtime常见用法

runtime是Objective-C上一个非常强大的屠龙刀,提供了很多奇幻的魔法,当然,如果过度滥用的话,维护上的代价也是显而易见的。 我们这里只讨论一下我们平常工作中常用的特性,当然,它有大量功能,只是我们并不一定用的到,类似objc_msgSend这种的我们也不作介绍。 Objective-C runtime已经开源了,有阅读源码习惯的程序员可以前往官网下载阅读。 下面是下载地址: http://www.opensource.apple.com/tarballs/objc4/ 添加、获取属性 以开源库SVPullToRefresh(SVPullToRefresh是一个提供上下拉刷新的库)举例。 在UIScrollView+SVPullToRefresh这个Category上,SVPullToRefresh 给UIScrollView动态添加了一个属性,我们以SVPullToRefreshView *pullToRefreshView这个属性举例。 在UIScrollView+SVPullToRefresh.h上先申明了这个属性 @property (nonatomic, strong, readonly) SVPullToRefreshView *pullToRefreshView; 之后,在UIScrollView+SVPullToRefresh.m中重写了它的Setter和Getter方法,分别如下: Setter: - (void)…

MongoDB数据空洞解决方法

本文链接:http://ifujun.com/mongodbshu-ju-kong-dong-jie-jue-fang-fa/ 背景 某一段时间,来了点兴趣,看了点Mongodb的书,所以写下了这篇博客,也算是一点总结吧。 很多时候,我们项目上线时间比较久了,我们积累了一些无用的数据,而由于MongoDB顺序写的原因,在我们删除部分无用数据后,它的storageSize和fileSize并不会变小,这就造成了大量的数据空洞。 这些数据空洞除了占用磁盘之外,也会加载到内存中,这会降低内存效率。 所以这个时候,我们一般要对这些数据空洞进行处理,一般有下面几种处理方式。 一种是使用MongoDB自带的compact命令: db.collectionName.runCommand(“compact”) 这种方式是collection级别的压缩,只能去除collection内的碎片,但是MongoDB的数据分配是DB级别的,效果并不一定多好,其次呢,这个压缩是线上压缩,肯定会影响服务的,磁盘IO会比较高,这么干容易出事。 还有一种方式,也就是我们下面要详细说明的方式,过程大概类似于下面: 先预热从库 提升从库为主库,原主库降为从库 移除原主库的DB数据,直接remove掉 重新同步 完成后,预热,然后将此库提升为主库,…

[译文]如何才能不崩溃 #9: Mindset

原文地址; http://inessential.com/2015/06/10/how_not_to_crash_9_mindset 你知道不写代码的保守派和你一样聪明(You know the old line about not writing code that’s as clever as you are),因为这可能需要一些更聪明的人来调试它? 我曾经认为我应该写和我一样聪明的人的80%左右的代码。留一点时间去调试。 但是在许多年之后,我想,我应该写和我一样聪明的人的10%左右的代码。我开始相信,真正聪明的是使代码非常清晰,并且使得代码明显看起来没有问题。 这就是为什么我有这样的规则:在主线程上做所有事情,除了可以被完美独立起来的和永远不要使用 unsafe_unretained。 这意味着我没有成为代码魔术师的加分点。我不会从帽子里面变出兔子,我也确定我不会走高空绳索。我甚至看都不看绳子。…

[译文]如何才能不崩溃 #8: Infrastructure

原文地址: http://inessential.com/2015/06/10/how_not_to_crash_8_infrastructure 即使你认为你的app不会崩溃,你依然需要收集崩溃日志 - 因为没有绝对的不崩溃:你只能避免已知的崩溃错误。 有很多不同的服务:我尝试过一些后觉得都不错,所以我不会做特殊建议。 但有几件事情应该要做: 崩溃日志应该不需要用户去找到并发送给你。它应该是自动的(如果在OS X系统上,用户可能应该被提示;但是在iOS上,没人希望看到提示。) 应该有一个聚集崩溃日志的方法,你应该能获取到所有聚集起来的崩溃日志组,那样你就能知道哪些是频繁的,而哪些不是。 你应该能够将某些组标记为已解决。 这不够,当然,只是为了收集崩溃日志。你应该定期查阅。(我每天早上都看一下崩溃日志。) 错误追踪 我有一套。 对于我个人的项目,我使用  Lighthouse 、OmniOutliner和笔和纸的组合 - 但是你应该使用任何适合你的工具,只要你进入你的错误追踪工具而不迷路。 (Lighthouse是一个很好的错误追踪工具。对于叙述整个app的未来,…

[译文]如何才能不崩溃 #7: Dealing with Nothing

原文地址: http://inessential.com/2015/05/29/how_not_to_crash_7_dealing_with_nothin 考虑一下这行代码: [thing doStuff]; 如果thing为空(nil),没有问题。不会崩溃。什么都不会发生。 但是你不能以此推断nil在任何情况下都OK: [self doStuff:thing]; 如果thing是nil,那么会发生什么?如果依赖于doStuff:的实现 - 那么,它可能会崩溃。考虑下面这行代码: menuItem.title = thing; 如果menuItem是一个NSMenuItem,那么当thing为nil的时候,它会崩溃。NSMenuItem的头文件上并没有说这些,文档也只提示了一下(“如果你不写title,请使用空字符串(@“”),不是nil。”) 这意味着你需要去确认thing不能为nil。你可能非常确信,thing不是nil。thing是一个字体的名字,…

[译文]如何才能不崩溃 #6: Properties and Accessors

原文地址: http://inessential.com/2015/05/27/how_not_to_crash_6_properties_and_acce 这让我毛骨悚然: - (void)someRandomMethod { some stuff… _thing = otherThing; other stuff… } 你可以证明这是正确的。你正在使用ARC,它会被适当的保持(retain)、释放(release)和添加(add)。没有人观察 _thing。 好吧。这合法并且它工作了。 你意识thing应该是可以被观察的。所以,每一个你设置thing的地方,你可以调用: [self willChangeValueForKey:kThingKey]; _thing = otherThing; [self didChangeValueForKey:kThingKey]; 依然合法,…