本次项目更新,需要做IMSDK的版本更新,所以将IMSDK和移动直播SDK更新到了V1最高版本,见https://www.jianshu.com/p/2a694736e588
本文章记录一下SDK更新后遇到的一些问题,和解决方式:
1、修复首页不显示未读消息数的问题
【问题排查】
排查发现,新SDK获取消息数的API改为异步,之前是同步,会卡住主线程,使其及其卡顿,并且逻辑混乱无法正常获取消息数
【解决方案】
通过dispatch_group,加notify的方式,开辟多个子线程,将过滤消息的for逻辑丢入到组中,最后通过notify的方式再回调到主线程实现。此方式不会卡住app,用户正常使用,当API处理完毕后,会回调到主线程,并在UI上展示消息数
2、停留在首页,收到新消息时,消息数显示不正确
【问题排查】
慢速收消息数量显示正确,但是消息发快了,数量增加的就不正确了,例如快速发送6条消息,消息数只增加了5。
因为之前处理接受消息数是在主线程处理的,很容易造成线程冲突,容易导致计数错误。
【解决方案】
现在将增加计数的逻辑处理放到子线程,处理之后再回调到主线程中。
处理之后,增加了1.1s的延迟,因为SDK的回调会有一些延迟,立即执行有时会过快,导致调用getUnReadMessageNum,拿不到实际的未读消息数(SDK的问题)。
3、修复私信列表不显示消息的问题
【问题排查】
初步断定存在2个问题:
(1)由于之前获取会话里面的消息是同步方法,新SDK改为异步方法,就无法同步执行下面的代码。
(2)之前获取我们自己的followsid的接口和获取用户列表信息的接口,都是使用同步网络请求,该操作结合SDK后都会卡住主线程,导致整个项目卡顿无法操作,也就无法获取到私信列表
【解决方案】
原项目代码构成:2个for循环中,第一个for中每次循环嵌套一个同步的获取消息方法,第二个for中每次循环嵌套一个同步获取消息的方法,循环之前有一个获取FollowIds的同步请求,2个for之间有一个获取用户信息列表的同步请求。
通过dispatch_group解决此问题
4、修复切到其他页面再切回主页会卡住不动的问题
【问题排查】
因为获取未读消息数,是写在首页viewDidAppear里面的,所以获取消息数会卡住主线程,同问题1
5、直播间久置会导致严重卡顿,导致cpu负荷从20%涨到100%+
【问题排查】
程序控制台一直打印《[+[CustomElemCmd parseCustom:] Line 47]自定义消息不是CustomElemCmd类型》这个警告,未更新IMSDK和移动直播SDK之前也有,不过很少,之前大概是1小时几万次,现在是1小时几十万次。
仔细排查后,占用CPU的罪魁祸首就在这
【解决方案】
由于新老SDK消息监听API变更,之前是无论添加几个监听者,都只会收到1次回调,老代码中,每次刷新都会添加1个监听者,这就导致每次收到新消息都会被复制几十上百次,直接导致卡顿,现在将监听者写在init中,那么全局就只有1个监听者,解决了此问题
- (int)addMessageListener:(id<TIMMessageListener>)listener;
6、放置在首页,会收到奇奇怪怪的各种别的群的点赞送礼等消息,正常不应该收到
【问题排查】
怀疑是进入直播间A,从A非正常退出后,再重启app,就能一直收到A群组的消息,退出A群组失败,或者未调用退出A群组的API
【解决方案】
在用户收到消息API中,若用户不是在直播间内,并且收到的是群组消息,且群组不是用户大群的情况下,先调用退出群API,之前也有这块的逻辑,不过有些不完善,现在我这种处理虽然解决了此问题,但是更新SDK之前并没有此问题,所以这个解决的不完美,需要继续深入排查。
- (void)onNewMessage:(NSArray*)msgs;
7、直播间内,用户送连发礼物(例如:苹果*999)就需要一个数字滚动动画,这时候当多个用户同时送,并且都是较多连发数的时候,会导致卡顿。
【问题排查】
送礼物数字滚动动画有问题,会卡住cpu,导致cpu负荷从40%涨到90%+,之前送礼物数字滚动动画是每0.01秒,执行一次数字+1,然后赋值给UILabel,如果送礼999,那么就会循环999次,多人送礼物的时候会导致占用cpu过大,之前没更新SDK之前没有问题,更新SDK后,会导致cpu占用近100%,就会卡住,具体原因未知,可能新IMSDK占用cpu增加了正好会导致。
【解决方案】
同问题8一起
8、当用户送连发礼物时,连发礼物数字滚动的同时,滑动公屏消息,礼物连发动画就会停止
【问题排查】
Runloop冲突
【解决方案】
首先之前是使用的
NSTimeInterval t = 1.6 / part;
[self performSelector:@selector(showNumAdd) withObject:nil afterDelay:t];
多次循环导致卡顿,并且出现问题8。
使用PPCounter解决此问题。
PPCounter使用的是CADisplayLink定时器,并且
[_timer addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
[_timer addToRunLoop:[NSRunLoop mainRunLoop] forMode:UITrackingRunLoopMode];
将timer添加到滚动runloop中防止冲突导致卡顿
同时也优化了999次循环的问题。
9、公屏消息面板滚动卡顿
【问题排查】
因为公屏来新消息的时候,需要将消息面板自动滚动到最新的消息,所以同时自动滚和手动滑就冲突了,看起来不流畅
【解决方案】
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView{
_canScrollToBottom = NO;
}
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
CGFloat offsetY = scrollView.contentOffset.y;
CGFloat realContentHeight = scrollView.contentSize.height - 150;
NSLog(@"~~~~~~~~~~~~%.2f", offsetY);
if (offsetY < (realContentHeight - 40)) {
_canScrollToBottom = NO;
} else {
_canScrollToBottom = YES;
}
if (!_canScrollToBottom) {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(kLiveMessageContentOffsetTime * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
self->_canScrollToBottom = YES;
});
}
}
10、iphoneX 系统14,运行项目崩溃,报错[TIMFriend copyWithZone:]: unrecognized selector sent to instance
【问题排查】
之前获取Firends的API是返回的 strings, 新SDK返回的是TIMFriends,类别冲突导致崩溃,但是不知道为啥iphone7p不崩溃,奇怪
【解决方案】
将原来的 friend 改为 firend.identifier 去获取id 即可,可能有其他API也存在这种问题,需要注意,后面详细测试时在具体看
11、私信列表,在刚进入,或者刷新后的第一次,有个会话收到新消息没有红点显示,若之前就有红点,则红点数不增加
【问题排查】
因为新IMSDK获取未读消息数的api,在立刻收到消息时就去调用,拿到的数据不准,所以在收到新消息通知时,增加一个异步延迟1s,然后再去获取未读消息数。
【解决方案】
同问题2
12、退出登录会崩溃
【问题排查】
发现退出登录时会崩溃,加了僵尸,加了全局断点,就是一直崩在main,控制台也无任何输出。
最后发现崩溃的代码是
@implementation IMAConversationManager
- (void)dealloc{
// [[TIMManager sharedInstance] removeMessageListener:self]; //这么写会崩溃,不知道为什么
}
我也不清楚为什么,是因为self已经是nil了吗?那腾讯写的东西也不应该崩溃才对。
【解决方案】
改到外面持有IMAConversationManager的类中,调用:
[[TIMManager sharedInstance] removeMessageListener:_conversationMgr];
_conversationMgr = nil;
解决了闪退问题。
持续更新中...