iOS https防止中间人攻击

“公钥” 和 “私钥”

首先要明白两个概念“公钥”和“私钥”,
“公钥” 可以理解成锁头,“私钥” 就是钥匙。我们可以把 “公钥” 给客户端用来加密数据,当数据传回来时再用私钥解开加密就可以看到真正的内容了。
https数字证书:里面包含公钥,一般签发证书时会得到一个与公钥配对的私钥。证书会在通信过程中传给客户端,客户端也可以放一个,用来对比和服务端传过来的是不是一致

Read More

OC对象下标索引和键索引

对于NSArrayNSDictionary我们可以通过下标直接访问对象,比如

1
2
3
4
NSArray *arr = @[@"a", @"b", @"c"];
arr[1]; // b
NSDictionary *dic = @{@"k1": @"v1", @"k2": @"v2", @"k3": @"v3"}
dic[@"k1"]; // v1

其实对于普通NSObject类,我们通过实现一些方法也可以实现类似功能

1
2
3
4
5
6
7
//实现类似数组下标索引只需实现以下方法
- (id)objectAtIndexedSubscript:(NSUInteger)idx;
- (void)setObject:(id)obj atIndexedSubscript:(NSUInteger)idx;

//实现类似字典键索引只需实现以下方法
- (id)objectForKeyedSubscript:(id)key;
- (void)setObject:(id)obj forKeyedSubscript:(id <NSCopying>)key;

Read More

等待异步block完成再返回

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
- (NSArray *)tasksForKeyPath:(NSString *)keyPath {
__block NSArray *tasks = nil;
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
[self.session getTasksWithCompletionHandler:^(NSArray *dataTasks, NSArray *uploadTasks, NSArray *downloadTasks) {
if ([keyPath isEqualToString:NSStringFromSelector(@selector(dataTasks))]) {
tasks = dataTasks;
} else if ([keyPath isEqualToString:NSStringFromSelector(@selector(uploadTasks))]) {
tasks = uploadTasks;
} else if ([keyPath isEqualToString:NSStringFromSelector(@selector(downloadTasks))]) {
tasks = downloadTasks;
} else if ([keyPath isEqualToString:NSStringFromSelector(@selector(tasks))]) {
tasks = [@[dataTasks, uploadTasks, downloadTasks] valueForKeyPath:@"@unionOfArrays.self"];
}

dispatch_semaphore_signal(semaphore);
}];

dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);

return tasks;
}

@property 详解

我们先来看两个版本代码
不使用@property版本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@interface User : NSObject
- (NSString *)name;
- (void)setName:(NSString *)name;
@end

@implement User {
NSString *_name;
}

- (NSString *)name {
return _name;
}

- (void)setName:(NSString *)name {
_name = [name copy];
}

@end

Read More

assign vs weak

ARC下assign和weak区别

assign 和 weak 非常相像,都不对引用计数加1。assign其实也可以修饰对象,但一般不这么做,为什么呢? 下面介绍下两者区别。
这两者主要区别就是weak比assign多了一个功能。当weak修饰的property指向的对象被释放时,该property会自动被置为nil,这样给该property发送任何消息都不会报错。而assign修饰的property指向的对象如果被释放,该property并不会自动被置为nil,这时如果该property指向的内存里结构发生变化,然后又向该property发送消息,那么就会造成野指针操作,导致app崩溃。

Read More

GCD vs NSOperation

GCD 和 NSOperation都是iOS多线程技术,在现在的实现中NSOperation还是基于GCD的封装。GCD是C-based API,把一个任务单元封装在一个block中,可以在c、c++中使用;NSOperation是Cocoa提供的,是一个objective-c抽象类,使用时你要继承它或直接使用系统提供的NSInvocationOperationNSBlockOperation类。
接下来我会分别对GCD和NSOperation进行介绍:

Read More

iOS APP启动流程

从网上看了iOS APP启动流程,这里简单记录下。
1.执行main()函数。
2.main()函数调用UIApplicationMain()
3.UIApplicationMain()创建UIApplication对象、UIApplicationDelegate对象,读取info.plist配置文件,设置程序启动的一些属性,创建Main RunLoop,用户与app所有交互都被一个一个传到Main RunLoop进行处理。
4.如果是通过Storyboard或xib启动app,则开始加载UI

Read More

UIView触摸事件

UIView触摸事件

1.响应者对象(UIResponder)

只有继承UIResponder的对象才能处理触摸事件,比如:

  • UIApplication
  • UIViewController
  • UIView

UIResponder提供了以下方法处理触摸事件

1
2
3
4
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event;

我们可以重写这些方法来处理触摸事件

Read More

UITableView 性能优化

UITableView 工作流程:

How to get cell in heightForRowAtIndexPath?

It’s impossible, because when -heightForRowAtIndexPath is called, no cells are created yet. You need to understand how the UITableView works:

  1. UITableView asks it’s datasource how many sections it will have

    1
    -numberOfSectionsInTableView

    At this point there are no cells created.

    Read More