黑魔法(method-swizzling)解决第三方库引发的问题

需求

最近做一个项目中,有个需求,所有网络请求,都不显示 NetworkActvityIndicator(也就是状态栏里旋转的小圈圈).

解决过程1:

全局搜索 NetworkIndicator 关键字, 把所有涉及 NetworkIndicator 的代码去除,比如 [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];

测试并发现新问题

所有界面都不再显示NetworkActvityIndicator了,唯独一个播放视频的界面依然显示。

猜想: 第三方库引发的问题

无论是哪些第三方库,正常情况都会通过 setNetworkActivityIndicatorVisible 来 显示状态栏小圈圈。

验证过程1

通过继承 UIApplication 来重写了 setNetworkActivityIndicatorVisible 方法。(如何继承UIApplication,请看这里)并把断点打在这个方法体内。

测试了正常调用 [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES]; 是会触发断点的。但是唯独那个视频界面,没有触发该断点的情况下,正常显示小圈圈。

验证过程2

通过 KVO 监听 UIApplication 的 networkActivityIndicatorVisible 属性,结果还是和 验证过程1 的情况一样。
正常调用 [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES]; 是会触发监听, 唯独那个视频界面,没有触发监听的情况下,正常显示小圈圈。

所以, 视频界面里显示的小圈圈,肯定不是通过常规调用 setNetworkActivityIndicatorVisible 方法显示出来的。

更新猜想: 第三方库引发的问题,并且不是通过常规方法调用

验证过程3

显示小圈圈的情况下,分析了该界面的视图层级,发现在 statusBar 上,有 类型为UIActivityIndicatorView的视图存在(并且怪异的存在了两个)。

那正常情况下,通过 [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES]; 显示小圈圈时,视图层级是如何的呢? 通过分析验证, 也是一样的。

层级都是 UIStatusBarView -> UIStatusBarForegroundView -> UIStatusBarActivityItemView -> UIActivityIndicatorView

想到解决方案:

既然小圈圈都是 UIActivityIndicatorView 类型的视图,而 UIActivityIndicatorView 开始动画常规都是调用 startAnimation 方法。
那何不使用黑魔法(method swizzling)来重写它的 startAnimation 方法,
判断它的superView是否为 “UIStatusBarActivityItemView”类型,如果是,则直接跳出。否则,执行原有的 startAnimation方法。

Talk is cheap. Show me the code.

以下是 .m 文件的代码

@implementation UIActivityIndicatorView (HideNetworkActivityIndicator)+ (void)load {static dispatch_once_t onceToken;dispatch_once(&onceToken, ^{Class class = [self class];SEL originalSelector = @selector(startAnimating);SEL swizzledSelector = @selector(xxx_startAnimating);Method originalMethod = class_getInstanceMethod(class, originalSelector);Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);// When swizzling a class method, use the following:// Class class = object_getClass((id)self);// ...// Method originalMethod = class_getClassMethod(class, originalSelector);// Method swizzledMethod = class_getClassMethod(class, swizzledSelector);BOOL didAddMethod =class_addMethod(class,originalSelector,method_getImplementation(swizzledMethod),method_getTypeEncoding(swizzledMethod));if (didAddMethod) {class_replaceMethod(class,swizzledSelector,method_getImplementation(originalMethod),method_getTypeEncoding(originalMethod));} else {method_exchangeImplementations(originalMethod, swizzledMethod);}});
}#pragma mark - Method Swizzling- (void)xxx_startAnimating{if (self.superview != nil && [NSStringFromClass([self.superview class]) isEqualToString: @"UIStatusBarActivityItemView"]) {NSLog(@"黑魔法禁止状态栏的loading显示: %@", self);} else {[self xxx_startAnimating];}}@end

成功了!!!

(在xxx_startAnimation方法体内打断点,程序进入视频播放界面,触发断点,看调用栈,果然是第三方库引发的问题。)

参考资料:https://nshipster.cn/method-s...

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/388213.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python 操作 MySQL 的5种方式(转)

Python 操作 MySQL 的5种方式 不管你是做数据分析,还是网络爬虫,Web 开发、亦或是机器学习,你都离不开要和数据库打交道,而 MySQL 又是最流行的一种数据库,这篇文章介绍 Python 操作 MySQL 的5种方式,你可以…

unity3d 人员控制代码

普通浏览复制代码private var walkSpeed : float 1.0;private var gravity 100.0;private var moveDirection : Vector3 Vector3.zero;private var charController : CharacterController;function Start(){charController GetComponent(CharacterController);animation.w…

删除wallet里面登机牌_登机牌丢失问题

删除wallet里面登机牌On a sold-out flight, 100 people line up to board the plane. The first passenger in the line has lost his boarding pass but was allowed in regardless. He takes a random seat. Each subsequent passenger takes their assigned seat if availa…

PHP 备份还原 MySql 数据库

原生 PHP 备份还原 MySql 数据库 支持 MySql,PDO 两种方式备份还原 php5.5 以上的版本建议开启pdo扩展,使用 pdo 备份还原数据 备份文件夹 db_backup、import/log 文件要有读写权限环境版本 本人测试环境 php:5.5.38 /5.6.27-nts/7.0.12-nts; mysql: 5.5…

Java™ 教程(Queue接口)

Queue接口 Queue是在处理之前保存元素的集合&#xff0c;除了基本的Collection操作外&#xff0c;队列还提供额外的插入、删除和检查操作&#xff0c;Queue接口如下。 public interface Queue<E> extends Collection<E> {E element();boolean offer(E e);E peek();…

字符串操作截取后面的字符串_对字符串的5个必知的熊猫操作

字符串操作截取后面的字符串We have to represent every bit of data in numerical values to be processed and analyzed by machine learning and deep learning models. However, strings do not usually come in a nice and clean format and require preprocessing to con…

最新 Unity3D鼠标滑轮控制物体放大缩小 [

var s 1.0;function Update () {var cube GameObject.Find("Cube");if(Input.GetAxis("Mouse ScrollWheel")){s Input.GetAxis("Mouse ScrollWheel");cube.transform.localScaleVector3(1*s,1*s,1*s);}}

sublime-text3 安装 emmet 插件

下载sublime&#xff0c;http://www.sublimetext.com/ 安装package control &#xff1a;https://packagecontrol.io/ins... 这个地址需要翻墙&#xff0c;访问不了的可以看下图 import urllib.request,os,hashlib; h 6f4c264a24d933ce70df5dedcf1dcaee ebe013ee18cced0ef93d…

数据科学家访谈录 百度网盘_您应该在数据科学访谈中向THEM提问。

数据科学家访谈录 百度网盘A quick search on Medium with the keywords “Data Science Interview” resulted in hundreds of Medium articles to help guide the reader from what concepts are covered to even specific company interviews ranging from Tesla, Walmart, …

unity3d]鼠标点击地面人物自动走动(也包含按键wasdspace控制)

目录(?)[-] 一效果图二大概步骤 创建一个plane设置层为Terrain因为后面要判断是否点击的是这个层准备好人物模型并且将三个脚本拖放到人物上并且将动画文件也拖放好记得看前面提醒哦 ThirdPersonCamera相当于smoothflowThirdPersonController修改版mouseMoveContr鼠标点击人物…

uva 524(Prime Ring Problem UVA - 524 )

dfs练习题,我素数打表的时候ji了&#xff0c;一直没发现实际上是ji*i&#xff0c;以后可记住了。还有最后一行不能有空格。。。昏迷了半天 我的代码(紫书上的算法) #include <bits/stdc.h> using namespace std; int bk[110]; int num[110]; int vis[110]; int n; void d…

Web 开发基础

一、 Web 开发简介 最早的软件都是运行在大型机上的&#xff0c;软件使用者登陆到大型机上去运行软件。后来随着 PC 机的兴起&#xff0c;软件开始主要运行在桌面上&#xff0c;而数据库这样的软件运行在服务器端&#xff0c;这种 Client/Server 模式简称 CS 架构。随着互联网的…

power bi函数_在Power BI中的行上使用聚合函数

power bi函数Aggregate functions are one of the main building blocks in Power BI. Being used explicitly in measures, or implicitly defined by Power BI, there is no single Power BI report which doesn’t use some sort of aggregate functions.聚合功能是Power BI…

关于如何在Python中使用静态、类或抽象方法的权威指南

Python中方法的工作方式 方法是存储在类属性中的函数&#xff0c;你可以用下面这种方式声明和访问一个函数 >>> class Pizza(object):... def __init__(self, size):... self.size size... def get_size(self):... return self.size...>&…

广义估计方程估计方法_广义估计方程简介

广义估计方程估计方法A key assumption underpinning generalized linear models (which linear regression is a type of) is the independence of observations. In longitudinal data this will simply not hold. Observations within an individual (between time points) …

css二

结构性伪类:nth-child(index)系列1.:first-child2.:last-child3.nth-last-child(index)4.only-child :nth-of-type(index)系列1.first-of-type2.last-of-type3.nth-last-type(index)4.only-of-type :not伪类处理导航栏最后一个竖划线a:not(:last-of-type) :empty伪类 选中所有内…

Unity3d鼠标点击屏幕来控制人物的走动

今天呢&#xff0c;我们来一起实现一个在RPG中游戏中十分常见的功能&#xff0c;通过鼠标点击屏幕来控制人物的走动。首先来说一下原理&#xff0c;当我们点击屏幕时&#xff0c;我们按照一定的方法&#xff0c;将屏幕上的二维坐标转化为三维坐标&#xff0c;然后我们从摄像机位…

Java中的ReentrantLock和synchronized两种锁定机制的对比

2019独角兽企业重金招聘Python工程师标准>>> 多线程和并发性并不是什么新内容&#xff0c;但是 Java 语言设计中的创新之一就是&#xff0c;它是第一个直接把跨平台线程模型和正规的内存模型集成到语言中的主流语言。核心类库包含一个 Thread 类&#xff0c;可以用它…

10.15 lzxkj

几天前写的&#xff0c;忘了放了&#xff0c;在此填坑 10月16的题我出的不写题解了 lzxkj 题目背景 众所不周知的是&#xff0c; 酒店之王 xkj 一个经常迷失自我的人 有一天&#xff0c; 当起床铃再一次打响的时候&#xff0c; TA 用 O(1)的时间在 TA 那早就已经生锈的大脑中自…

大数定理 中心极限定理_中心极限定理:直观的遍历

大数定理 中心极限定理One of the most beautiful concepts in statistics and probability is Central Limit Theorem,people often face difficulties in getting a clear understanding of this and the related concepts, I myself struggled understanding this during my…