0%

有些时候,我们会想要一个同步的网络请求,而不用在AFN的回调里等待,层层嵌套。此外一些异步操作也希望按顺序来执行,

阅读全文 »

在第二份工作前,我是手写UI的忠实拥护者,顶多用xib自定义cell。在交互原型和后台数据都确定的情况下,很难会有很大的改动,而且用数据驱动页面,做一些微调,看着就很优雅。切图、标注、备注和完善的后台文档,做客户端开发可以说是行云流水,而且,自然而然地想做更多的优化。

阅读全文 »

为了提高客户端内容加载速度与效率,在加载网络图片时,会使用缓存,而SDWedImage可以说是iOS 网络图片加载的事实标准了。但它并没有一种较好的缓存策略,解决URL不变图片改变的情况。

阅读全文 »

charles 这个神器提供非常简便的方法,查看设备的http甚至https请求,但无法抓到TCP包,所以,要进行TCP抓包,还得用一些较原始的工具。

阅读全文 »

问题

大家都知道使用block的时候可以通过__weak关键字来避免循环引用,如下:

1
2
3
4
5

protocol Navigatable {
var navigator: Navigator! { get set }
}

1
2
3
4
__weak typeof(self) weakSelf = self;
self.handler = ^{
NSLog(@"Self is %@", weakSelf);
};
阅读全文 »

不多不少写了三四万行的iOS代码,但调试方法一直没怎么学习,最常用就用NSLog输出和打断点了,这在开发自己的项目时可能觉得还能接受,但在看别人的项目代码时就是一种折磨,那么现在来稍微学点LLDB调试技巧。

两个重要命令的使用

watchpoint

主要用于观察变量值的具体变化
比如需要观察某个变量x的值变化,可以使用以下命令

1
(lldb) watchpoint set variable a

成功添加watchpoint后结果如下

1
2
3
4
(lldb) watchpoint set variable _bookNameArray
Watchpoint created: Watchpoint 1: addr = 0x7fe61ba045f8 size = 8 state = enabled type = w
watchpoint spec = '_bookNameArray'
new value: 0x0000000000000000

用frame命令查看变量具体值

1
2
frame variable _bookNameArray
(NSMutableArray *) _bookNameArray = nil

设置变量变化为某个特定值后打印相关信息,下面设置对象不为空时触发

1
2
3
4
5
6
7
8
9
10
(lldb) watchpoint modify -c '(_bookNameArray!=nil)'
2017-02-17 16:44:14.357 PageBoy[2814:172446] 0x60800006a980
2017-02-17 16:44:14.358 PageBoy[2814:172446] 0x60000004dd10
2017-02-17 16:44:14.359 PageBoy[2814:172446] 书名:西厢记
2017-02-17 16:44:14.359 PageBoy[2814:200714] XPC connection interrupted
2017-02-17 16:44:14.360 PageBoy[2814:172446] _bookName的长度:1

Watchpoint 1 hit:
old value: 0x0000000000000000
new value: 0x000060000004dd10

image

快速定位错误代码
测试代码,数组越界

1
2
NSArray *arr=[[NSArray alloc] initWithObjects:@"1",@"2", nil];
NSLog(@"%@",arr[2]);

运行后报错

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[__NSArrayI objectAtIndex:]: index 2 beyond bounds [0 .. 1]'
*** First throw call stack:
(
0 CoreFoundation 0x00007fffab6b1e7b __exceptionPreprocess + 171
1 libobjc.A.dylib 0x00007fffc029bcad objc_exception_throw + 48
2 CoreFoundation 0x00007fffab5d474c -[__NSArrayI objectAtIndex:] + 156
3 test 0x0000000100000eb2 main + 146
4 libdyld.dylib 0x00007fffc0b7f255 start + 1
5 ??? 0x0000000000000001 0x0 + 1
)
```
除了test其它都是系统的库,利用image的lookup命令可以定位到代码所在文件的行数

```objc
(lldb) image lookup --address 0x0000000100000eb2
Address: test[0x0000000100000eb2] (test.__TEXT.__text + 146)
Summary: test`main + 146 at main.m:21

显示错误代码在main.m文件的第21行

简介

LLDB 是一个有着 REPL 的特性和 C++ ,Python 插件的开源调试器。LLDB 绑定在 Xcode 内部,存在于主窗口底部的控制台中。调试器允许你在程序运行的特定时暂停它,你可以查看变量的值,执行自定的指令,并且按照你所认为合适的步骤来操作程序的进展。

阅读全文 »

在需要统计用户行为的时候,传统点做法就是在需要统计的地方加入响应的代码,如viewWillAppear、viewWillDisappear和一些交互事件中。优雅一点可以自定义一个控制器让其它控制器继承。代码耦合,扩展性差,不易维护,这些都是上述的方法的一些弊端。昨天说的Runtime黑魔法可以很优雅方便地解决这些弊端。

阅读全文 »

没怎么用过运行时,做毕设的时候拿来改了一下textfield的光标颜色,了解实在有限。现在来了解一下除简单获取私有变量的其它综合用途。

阅读全文 »

在一个iOS群里看到有人在学安卓,讨论怎么下IDE。Android Studio,刚出来的时候我就想下来玩玩,无奈那时候穿墙姿势不优雅,IDE是下回来了,磕磕碰碰到最后SDK还是没下回来。那现在就下回来跑跑以前刚学Java时写的安卓小程序。
这次下载安装AS、下SDK、下模拟器ROM包用了半个钟头左右,随便跑个helloworld是可以的,但是之前写的那个查区号的源代码不见了,当时都不知道github是什么,电脑都换了一次,也不是什么重要的东西,看来是删了。这个程序我打包过的,发到以前在顺丰做兼职时的群里,于是我下来装在了那台mt15i上,突然想到,听说安卓反编译很简单啊,我这个菜鸟写的源码,搞出源码应该不难吧,说干就干,上Google爬教程。

阅读全文 »