Releases: ChenYilong/iOSBlog
iOS开发笔记
iOSDevelopmentTips iOS开发笔记
- 《iOS9适配系列教程》
- 《iOS10适配系列教程》
- 《iOS11适配系列教程》
- 《Parse源码学习》
- 《HTTP状态码汇总》
- 《大话Socket》
- 《IM 即时通讯技术在多应用场景下的技术实现,以及性能调优(iOS视角)》
- 《基于WebRTC的视频聊天技术在iOS端的实现》
- 《使用 Heap-Stack Dance 替代 Weak-Strong Dance,优雅避开循环引用》
- 《避免使用 GCD Global 队列创建 Runloop 常驻线程》
- 《iOS 常见耗电量检测方案调研》
- 《[EN]How to Fullscreen Xcode and Simulator?[CN]如何让 Xcode10 与模拟器同时进入分屏模式?》
- 《领悟到 NSCoding 是一个坑,Apple 花了10年时间》
Posted by 微博@iOS程序犭袁
原创文章,版权声明:自由转载-非商用-非衍生-保持署名 | Creative Commons BY-NC-ND 3.0
iOS 面试题系列
iOS 面试题系列
iOS面试题集锦(附答案)
- 第一篇 : 《招聘一个靠谱的 iOS》—参考答案(上)
- 第二篇 : 《招聘一个靠谱的 iOS》—参考答案(下)
微信群面试题系列
Posted by 微博@iOS程序犭袁
原创文章,版权声明:自由转载-非商用-非衍生-保持署名 | Creative Commons BY-NC-ND 3.0
iTeaTime(技术清谈)【001期】【代号:海王】
iTeaTime(技术清谈)【001期】【代号:海王】
出题:微博@iOS程序犭袁
本期代号:海王
1.【问题】【iOS】请问前后台切换,会发生些什么,系统哪些方法会被调用,viewcontroller哪些方法会被调用
【答案】
在不考虑 APP 在后台被 kill 的情况:
进入后台:
方法 | 作用 |
---|---|
applicationWillResignActive |
点击 Home 键,app 开始准备进入后台, 这个时候会进入该回调,意味着 app 被挂起,进程即将失去活跃。 经过不严谨的测试,大约有 10 分钟左右的时间用来处理事务。 |
applicationDidEnterBackground |
当 applicationWillResignActive 回调方法完全执行完毕后, 会进入 applicationDidEnterBackground 。 |
进入前台:
方法 | 作用 |
---|---|
applicationWillEnterForeground |
在 app 未被杀死的情况下,点击 icon 再次进入 app, 重新回到前台之前会先进入 applicationWillEnterForeground 回调 |
applicationDidBecomeActive |
当 applicationWillEnterForeground 执行完毕后,会进入 applicationDidBecomeActive 回调,正式回归活跃。 |
前后台切换,主要的坑点在于:VC中并没函数会调用,尤其注意:VC 相关的 Appear 和 Disappear 函数并不会被调用。想在VC中监听切换,只能监听通知,每个在appdelegate的生命代理方法都有对应的通知。
如果考虑 APP 在后台被 kill 的情况:
进入后台后,如果没有后台运行权限及功能,可能在一段时间后被系统 kill 掉,再次进入app后,会重新进入启动流程。
方法 | 作用 |
---|---|
main() 函数: | 这个阶段一般是 可执行 .o 文件,动态库加载,objc 类注册,category 类注册, selector 唯一性检查,+(void)load 方法,C++ 静态全局变量的创建等。 |
didFinishLaunchingWithOptions |
用户点击 icon 启动 app,或者被 kill 后以任何方式进入 app, 在 main() 执行后,会进入 didFinishLaunchingWithOptions 回调, 处理首屏渲染,以及其他业务相关的事件,例如监听事件, 配置文件读写或者 SDK 初始化等等。 |
applicationDidBecomeActive |
在 didFinishLaunchingWithOptions 方法作用域结束后, 会进入 applicationDidBecomeActive 回调, 也正式意味着 app 已经处于活跃状态。 |
rootViewController 的相关的 Appear 函数 | 注意:此时 rootViewController 的相关的 Appear 函数会被调用。 |
参考链接:
标题&链接 | 手机端阅读 |
---|---|
标题:WWDC 2016 - Session 406-Optimizing App Startup Time 链接:https://developer.apple.com/videos/play/wwdc2016/406/ |
2 【问题】【iOS】请问对无序的Array排序,有什么好的方法,代码越少,API越高级越好。有无原生方法可以办到。
苹果为我们提供了很多 Array 的排序方法,但原理上可以看到就是 Comparator (比较器) 和 Descriptor (描述器) 两种,像是 Selector 和 Function ,最终也是使用 Comparator 在做排序,只是响应方法不同。
其中 Swift 也有方法: array.sort(),见
参考链接:
标题&链接 | 手机端阅读 |
---|---|
标题:Apple Documentation-Swift-Array-sorted 链接:https://developer.apple.com/documentation/swift/array/2296815-sorted |
先说说 Comparator ,如果数组中元素是 String 或 Number,首选 Comparator,可以将 compare: 方法的返回值直接作为 NSComparisonResult 返回值。实际的排序代码三行就可以搞定。当然用 Selector 和 Function,也是一样的效果,但需要写更多的代码。
例子一:
NSArray *sortedArray = [array sortedArrayUsingComparator:^NSComparisonResult(NSString *obj1, NSString *obj2) {
if ([obj1 compare:obj2] == NSOrderedAscending) {
return NSOrderedAscending;
} else if ([obj1 compare:obj2] == NSOrderedDescending){
return NSOrderedDescending;
}else {
return NSOrderedSame;
}
}];
例子二:
- (void)arraySortUsingCompare {
// 比较器 排序
NSMutableArray *arr = [NSMutableArray array];
for (int i = 0; i < 10; i ++) {
int n = arc4random() % (10 - 0) + 1;
[arr addObject:@(n)];
}
NSLog(@"排序前 ===== %@", arr);
[arr sortUsingComparator:^NSComparisonResult(NSNumber *num1, NSNumber *num2) {
// return [num1 compare:num2]; // 正序
return [num2 compare:num1]; // 倒序
}];
NSLog(@"排序后 %@", arr);
arr = [NSMutableArray array];
[arr addObject:@"Kobe Bryant"];
[arr addObject:@"LeBorn James"];
[arr addObject:@"Steve Nash"];
[arr addObject:@"Stephen Curry"];
[arr addObject:@"Monkey D Luffy"];
[arr addObject:@"Roronoa Zoro"];
NSLog(@"排序前 ==== %@", arr);
[arr sortUsingComparator:^NSComparisonResult(NSString *str1, NSString *str2) {
// return [str1 compare:str2]; // 正序
return [str2 compare:str1]; // 倒序
}];
NSLog(@"排序后 %@", arr);
}
参考链接:
标题&链接 | 手机端阅读 |
---|---|
标题: 《Objective-C中的排序及Compare陷阱》 链接:https://blog.csdn.net/u011883764/article/details/38868097 |
但是如果需要针对一个对象的几个属性作为不同的维度去做排序,那选择 Descriptor,因为不需要根据利用属性对排序优先级写一大堆的逻辑判断。主要将所有参与比较的属性都放入描述器中即可,如果想对球员的年龄和号码(优先级分先后)进行排序,只需要依次加入描述器组,三行代码就可以完成。
- (void)arraySortUsingDescriptor {
NSMutableArray *arr = [NSMutableArray array];
Person *person = [[Person alloc] init];
person.name = @"Ingram";
person.age = 21;
person.number = 14;
[arr addObject:person];
person = [[Person alloc] init];
person.name = @"Ball";
person.age = 21;
person.number = 2;
[arr addObject:person];
person = [[Person alloc] init];
person.name = @"Zubac";
person.age = 21;
person.number = 15;
[arr addObject:person];
NSSortDescriptor *ageDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"age" ascending:YES];
NSSortDescriptor *numberDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"number" ascending:YES];
[arr sortUsingDescriptors:@[numberDescriptor, ageDescriptor]];
for (Person *person in arr) {
NSLog(@"\n 球员姓名: %@ \n 球员号码: %d \n 球员年龄: %d \n -------- \n", person.name, person.number, person.age);
}
}
3【问题】【iOS】请问APNs推送如何区分设备,如何将设备的信息传给Apple,你上传的时机时怎样的,猜想这个设备信息是如何生成的
【答案】
【设备信息传递给apple】
post请求;
Use HTTP/2 and TLS 1.2 or later to establish a connection between your provider server and one of the following servers:
• Development server: api.sandbox.push.apple.com:443
• Production server: api.push.apple.com:443
也就是:
设备信息是通过一个 POST 请求将 DeveiceToken 和其他信息发送给 APNS,需要用 HTTP/2 和 TLS 1.2 或以上的版本,在自己提供的服务和以上服务之间建立连接。
- 开发环境: api.sandbox.push.apple.com:443
- 生产环境:api.push.apple.com:443
当然,还可以用一台机器的 2197 端口让 APNS 通过防火墙
请求示例:
HEADERS
- END_STREAM
+ END_HEADERS
:method = POST
:scheme = https
:path = /3/device/00fc13adff785122b4ad28809a3420982341241421348097878e577c991de8f0
host = api.sandbox.push.apple.com
authorization = bearer eyAia2lkIjogIjhZTDNHM1JSWDciIH0.eyAiaXNzIjogIkM4Nk5WOUpYM0QiLCAiaWF0I
jogIjE0NTkxNDM1ODA2NTAiIH0.MEYCIQDzqyahmH1rz1s-LFNkylXEa2lZ_aOCX4daxxTZkVEGzwIhALvkClnx5m5eAT6
Lxw7LZtEQcH6JENhJTMArwLf3sXwi
apns-id = eabeae54-14a8-11e5-b60b-1697f925ec7b
apns-expiration = 0
apns-priority = 10
apns-topic = com.example.MyApp
DATA
+ END_STREAM
{ "aps" : { "alert" : "Hello" } }
【上传时机】didRegisterForRemoteNotificationsWithDeviceToken
方法,回调内处理设备信息上传的业务。但有些情况是,我们希望根据用户账号来做推送,例如即时通讯应用。那么我们就要在登录或自动登录后,上传deviceToken,和用户信息绑定并处理替换逻辑,避免推送错乱。
【设备信息】This address takes the form of a device token unique to both the device and your app.
猜测:UDID+bundleId+生产/开发环境+时间戳。
其中注意带时间戳hash是为什么频繁上传device token的主要原因。长期不活跃app,比如用户一个月或者两个月没打开过该app,该服务器后端就再也推不到了。
4【问题】【前端】js中,this指向性问题如何解决。
【答案】「.bind(this) 或 用箭头函数」「const that = this;」
5【算法】我如果说我每天都在处理昨天和前天产生的bug,那么我是一个什么类型的程序员。
【答案】斐波那契程序员,这个梗可以参考:斐波那契数列。
原文标题 & 原文链接 | 手机端阅读 |
---|---|
标题:《iTeaTime(技术清谈)【001期】【代号:海王】》 链接:iteatimeteam/Friday-QA#2 |
<im... |