内容简介:“1、需要明确:无论你有没有用 NSURLProtocol 对 app 中的所有网络请求做统一处理,这些网络请求的发起者都应该是无感知的。举个例子,在某个业务场景下,我使用自定义的 URLSession 发起网络请求,并实现各个代理方法来处理网络请求各个阶段的事件。如果这个网络请求被 NSURLProtocol 拦截,仍然需要保证当初实现的各个代理方法都能被如期调用。为此,苹果定义了2、很多介绍 NSURLProtocol 的文章,会在每个
“ 使用 NSURLProtocol 拦截网络请求 ”相信很多人都有所耳闻,最近出于工作需要比较详细地研究了一番,下面给出一些比较有用的踩坑总结。
1、需要明确:无论你有没有用 NSURLProtocol 对 app 中的所有网络请求做统一处理,这些网络请求的发起者都应该是无感知的。举个例子,在某个业务场景下,我使用自定义的 URLSession 发起网络请求,并实现各个代理方法来处理网络请求各个阶段的事件。如果这个网络请求被 NSURLProtocol 拦截,仍然需要保证当初实现的各个代理方法都能被如期调用。为此,苹果定义了 NSURLProtocolClient
协议,协议方法覆盖了网络请求完整的生命周期。只要你在拦截之后重发的请求的各阶段适时、完整地调用了协议中的方法,那么最初的请求发起者便对“拦截”这件事毫无感知了,它的代理事件或者回调的 block 都会在正确的时间被执行,无论这个请求最初是个 NSURLSessionDownloadTask
还是 NSURLConnection
。从这个角度来说,NSURLProtocol 是一个底层的拦截。
2、很多介绍 NSURLProtocol 的文章,会在每个 startLoading
方法的实现中,都创建 NSURLSession 实例,这是非常低效、失当的做法,具体原因其实和 NSURLProtocol 无关了,这是 NSURLSession 使用失当的问题。正确的实现应该是模拟 AFNetworking 的 SessionManager
,共享一个 session 实例,却可以将归属于每一个 task 的回调事件交由每一个 NSURLProtocol 实例处理,具体可以参考官方给出的 NSURLProtocol demo。或者,甚至可以直接使用 AFNetworking 来对拦截后的请求进行重发。
3、拦截重发一个 Request 之后,记得使用 setProperty:forKey:inRequest:
方法对该 Request 进行标记,防止进入死循环。
4、通过配置 Configuration
自定义的 Session 发出的请求,默认是无法被拦截到的,因为 NSURLSessionConfiguration
的属性 protocolClasses
里面,默认不包含我们自定义的 NSURLProtocol。这时,可以 hook protocolClasses 方法,加入我们自己的 protocol。
5、有的同学可能会纠结,最初的网络请求如果是一个 NSURLSessionDownloadTask
,它需要处理带有已写入数据、完整数据等信息的回调方法,而在 NSURLProtocol 中被拦截之后,统一采用 NSURLSessionDataTask 来重发,那当初的下载独有的代理方法,还能被正确执行吗?答案是肯定的,原因参考第一条。其实通过 NSURLProtocol 只提供了 NSURLRequest 来初始化的方法就可以看出来,在 NSURLProtocol 中,我们不需要关注最初的任务是何种 task,因为无论最初是什么类型的 task,到 protocol 的初始化这里时,你已经无法获知它最初的 task 类型。
WKWebView 给 scrollView 添加 delegate crash
作者:Lefe_x
想监听 WKWebView 的滚动,我的做法是设置 WKWebView.scrollView.delegate
,然而这种方法会导致在 iOS9 上 crash。使用全局断点并不能定位到 crash 的具体位置,当 crash 后,在打印控制台处输入 bt
,发现有输出异常信息,大体意思是 WKWebView 已经释放,但在其它地方还在使用它的属性 scrollView。
关于这个 crash 的描述:
Possible crash when setting the WKWebViews's scroll view delegate, if the scroll view outlives the web view Null out the internal delegate on the WKScrollView when the WKWebView goes away, since it's possible for a client to set its own scroll view delegate, forcing the creation of a WKScrollViewDelegateForwarder, and then retain the UIScrollView past the lifetime of the WKWebView. In this situation, the WKScrollViewDelegateForwarder's internalDelegate would point to a deleted WKWebView.
想解决这个问题需要在,dealloc 的位置把 delegate 设置为 nil:
self.webView.scrollView.delegate = nil; 复制代码
参考:
- Webkit trac.webkit.org/changeset/1…
不需要接入 SDK 的三方登录及分享
**作者:**这个汤圆没有馅
提到三方登录分享,第一反应大概是友盟、ShareSDK 之类。集成微信、QQ、微博三个平台,友盟 SDK 大小 62.9M,ShareSDK 大小 74M,如果直接集成三个平台的官方 SDK,分别大小如图,则一共有 51M。
接入 SDK 后,在授权登录的回调里拿到各个平台需要的值,再丢给后台,由后台去请求用户信息再与自己的用户体系绑定。(当然每个人的方案可能不一样,这只是其中一种) 如图下图,微信需要 code ,QQ 需要 openId 和 accessToken,微博需要 access_token。
这边介绍一个叫 MonkeyKing
( github.com/nixzhu/Monk… ) 的 Swift 库,文件大小只有121KB,通过直接访问url的方法拿到回调。
先调用 MonkeyKing.registerAccount
注册各个平台,再如图三调用授权登录的方法。
看了一下源码,实现原理如下:
- 微信:通过 weixin://app/YourAppId/auth/?scope=snsapi_userinfo&state=Weixinauth 拿到 code 值;
- QQ:通过 mqqOpensdkSSoLogin://SSoLogin/tencentXXX/com.tencent.tencentXXX?generalpastboard=1 拿到 openId 和 accessToken;
- 微博:是先设置剪切板参数,再通过 weibosdk://request?id=uuidString&sdkversion=003203000 获取access_token;
MonkeyKing 除了登录功能外,还有分享及支付功能等。而这些功能的实现不需要集成任何 SDK,对 App 体积大小有要求的人来说,这个库相当棒。
instancetype
和 id
的区别
作者:Vong_HUST
日常开发中,我们通常会复写各种指定构造器或者自定义指定构造器,一般返回值都会写成 instancetype,但是为什么要写 instancetype 而不是 id 呢?他们之间的区别在哪呢?
我们先来看下代码
@interface TestObjectA : NSObject + (id)createObjectA; - (void)methodA; @end @interface TestObjectB : NSObject + (instancetype)createObjectB; - (void)methodB; @end // 假设上面4个方法都有实现 [[TestObjectA createObjectA] methodB]; // 无编译错误,但是崩溃 [[TestObjectB createObjectB] methodA]; // 编译报错:No visible @interface for 'TestObjectB' declares the selector 'methodA' 复制代码
从上图可以看出,区别就在于: instancetype
能够做到类型检测而 id
不行。前者仅可做方法返回值,不能作为参数。但是可能会有人会有疑问,为什么 - (id)initWithxxx:
也可以做到类型检测呢?因为类方法只要以 alloc
、 new
开头就会有关联返回类型(即类型检测),实例方法只要以 init
、 autorelease
、 retain
、 self
开头就会有关联返回类型。具体可以参考这篇文章
但是 ARC 下实测,实例方法只有 init
开头的才有关联返回类型。
关注我们
欢迎关注我们的公众号:iOS-Tips,也欢迎加入我们的群组讨论问题。可以公众号留言 ios
、 flutter
、 web
、 pwa
、 小程序
等关键词获取入群方式。
目前 iOS 3号群
已到 300+,期待你的加入。
以上所述就是小编给大家介绍的《「 iOS知识小集 」2018 · 第 30 期》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 肖仰华谈知识图谱:知识将比数据更重要,得知识者得天下
- 基础知识:css3核心知识整理
- 从知识工程到知识图谱全面回顾 | AI&Society
- 知识图谱发展的难点&构建行业知识图谱的重要性
- 《面试知识,工作可待:集合篇》:Java 集合面试知识大全
- 第四期知识与认知图谱:神经机器翻译也应该嵌入「知识」
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Effective STL中文版
[美]Scott Meyers / 潘爱民、陈铭、邹开红 / 清华大学出版社 / 2006-1 / 30.00元
STL是C++标准库的一部分。本书是针对STL的经验总结,书中列出了50个条款,绝大多数条款都解释了在使用STL时应该注意的某一个方面的问题,并且详尽地分析了问题的来源、解决方案的优劣。一起来看看 《Effective STL中文版》 这本书的介绍吧!