Open ChenYilong opened 5 years ago
出题:微博@iOS程序犭袁 本期代号:海王
【答案】
在不考虑 APP 在后台被 kill 的情况:
进入后台:
applicationWillResignActive
applicationDidEnterBackground
进入前台:
applicationWillEnterForeground
applicationDidBecomeActive
前后台切换,主要的坑点在于:VC中并没函数会调用,尤其注意:VC 相关的 Appear 和 Disappear 函数并不会被调用。想在VC中监听切换,只能监听通知,每个在appdelegate的生命代理方法都有对应的通知。
如果考虑 APP 在后台被 kill 的情况:
进入后台后,如果没有后台运行权限及功能,可能在一段时间后被系统 kill 掉,再次进入app后,会重新进入启动流程。
didFinishLaunchingWithOptions
参考链接:
WWDC 2016 - Session 406-Optimizing App Startup Time
苹果为我们提供了很多 Array 的排序方法,但原理上可以看到就是 Comparator (比较器) 和 Descriptor (描述器) 两种,像是 Selector 和 Function ,最终也是使用 Comparator 在做排序,只是响应方法不同。
其中 Swift 也有方法: array.sort(),见
先说说 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); }
但是如果需要针对一个对象的几个属性作为不同的维度去做排序,那选择 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); } }
【设备信息传递给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 或以上的版本,在自己提供的服务和以上服务之间建立连接。
当然,还可以用一台机器的 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,和用户信息绑定并处理替换逻辑,避免推送错乱。
didRegisterForRemoteNotificationsWithDeviceToken
【设备信息】This address takes the form of a device token unique to both the device and your app.
猜测:UDID+bundleId+生产/开发环境+时间戳。
其中注意带时间戳hash是为什么频繁上传device token的主要原因。长期不活跃app,比如用户一个月或者两个月没打开过该app,该服务器后端就再也推不到了。
【答案】「.bind(this) 或 用箭头函数」「const that = this;」
【答案】斐波那契程序员,这个梗可以参考:斐波那契数列。
Posted by 微博@iOS程序犭袁 & 公众号@iTeaTime技术清谈 原创文章,版权声明:自由转载-非商用-非衍生-保持署名 | Creative Commons BY-NC-ND 3.0
--------------------------------------------
One more thing...
【非礼勿视】以下为彩蛋部分,建议28岁以上男性观看
iTeaTime(技术清谈)【001期】【代号:海王】
出题:微博@iOS程序犭袁 本期代号:海王
1.【问题】【iOS】请问前后台切换,会发生些什么,系统哪些方法会被调用,viewcontroller哪些方法会被调用
【答案】
在不考虑 APP 在后台被 kill 的情况:
进入后台:
applicationWillResignActive
这个时候会进入该回调,意味着 app 被挂起,进程即将失去活跃。
经过不严谨的测试,大约有 10 分钟左右的时间用来处理事务。
applicationDidEnterBackground
会进入 applicationDidEnterBackground 。
进入前台:
applicationWillEnterForeground
重新回到前台之前会先进入
applicationWillEnterForeground
回调applicationDidBecomeActive
applicationWillEnterForeground
执行完毕后,会进入 applicationDidBecomeActive 回调,正式回归活跃。
前后台切换,主要的坑点在于:VC中并没函数会调用,尤其注意:VC 相关的 Appear 和 Disappear 函数并不会被调用。想在VC中监听切换,只能监听通知,每个在appdelegate的生命代理方法都有对应的通知。
如果考虑 APP 在后台被 kill 的情况:
进入后台后,如果没有后台运行权限及功能,可能在一段时间后被系统 kill 掉,再次进入app后,会重新进入启动流程。
selector 唯一性检查,+(void)load 方法,C++ 静态全局变量的创建等。
didFinishLaunchingWithOptions
在 main() 执行后,会进入 didFinishLaunchingWithOptions 回调,
处理首屏渲染,以及其他业务相关的事件,例如监听事件,
配置文件读写或者 SDK 初始化等等。
applicationDidBecomeActive
会进入 applicationDidBecomeActive 回调,
也正式意味着 app 已经处于活跃状态。
参考链接:
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(),见
参考链接:
链接:https://developer.apple.com/documentation/swift/array/2296815-sorted
先说说 Comparator ,如果数组中元素是 String 或 Number,首选 Comparator,可以将 compare: 方法的返回值直接作为 NSComparisonResult 返回值。实际的排序代码三行就可以搞定。当然用 Selector 和 Function,也是一样的效果,但需要写更多的代码。
例子一:
例子二:
参考链接:
链接:https://blog.csdn.net/u011883764/article/details/38868097
但是如果需要针对一个对象的几个属性作为不同的维度去做排序,那选择 Descriptor,因为不需要根据利用属性对排序优先级写一大堆的逻辑判断。主要将所有参与比较的属性都放入描述器中即可,如果想对球员的年龄和号码(优先级分先后)进行排序,只需要依次加入描述器组,三行代码就可以完成。
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 或以上的版本,在自己提供的服务和以上服务之间建立连接。
当然,还可以用一台机器的 2197 端口让 APNS 通过防火墙
请求示例:
【上传时机】
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,那么我是一个什么类型的程序员。
【答案】斐波那契程序员,这个梗可以参考:斐波那契数列。
链接:https://github.com/iteatimeteam/Friday-QA/issues/2
Posted by 微博@iOS程序犭袁 & 公众号@iTeaTime技术清谈 原创文章,版权声明:自由转载-非商用-非衍生-保持署名 | Creative Commons BY-NC-ND 3.0
--------------------------------------------
One more thing...
【非礼勿视】以下为彩蛋部分,建议28岁以上男性观看
-------------------------------------------- ![image](https://user-images.githubusercontent.com/2911921/57273775-a32fc680-70cb-11e9-8cfd-2475e0abbb22.png)