Files
peko-ios/YuMi/Modules/YMRoom/View/MessageContainerView/Model/XPMessageDataSourceManager.m

255 lines
7.6 KiB
Objective-C

//
// XPMessageDataSourceManager.m
// YUMI
//
// Created by YUMI on 2024/12/19.
//
#import "XPMessageDataSourceManager.h"
@interface XPMessageDataSourceManager ()
/// 所有消息(内部可变)
@property (nonatomic, strong) NSMutableArray *allMessages;
/// 聊天消息(内部可变)
@property (nonatomic, strong) NSMutableArray *chatMessages;
/// 礼物消息(内部可变)
@property (nonatomic, strong) NSMutableArray *giftMessages;
/// 数据操作串行队列
@property (nonatomic, strong) dispatch_queue_t dataQueue;
@end
@implementation XPMessageDataSourceManager
#pragma mark - Initialization
- (instancetype)init {
return [self initWithMaxMessages:1000];
}
- (instancetype)initWithMaxMessages:(NSInteger)maxMessages {
self = [super init];
if (self) {
_allMessages = [NSMutableArray array];
_chatMessages = [NSMutableArray array];
_giftMessages = [NSMutableArray array];
_dataQueue = dispatch_queue_create("com.yumi.message.data", DISPATCH_QUEUE_SERIAL);
_maxMessages = maxMessages;
}
return self;
}
#pragma mark - Public Methods
- (void)addMessage:(XPMessageItem *)message {
if (!message) return;
dispatch_async(self.dataQueue, ^{
NSMutableArray *allMessages = (NSMutableArray *)_allMessages;
NSMutableArray *chatMessages = (NSMutableArray *)_chatMessages;
NSMutableArray *giftMessages = (NSMutableArray *)_giftMessages;
[allMessages addObject:message];
// 根据消息类型分发到对应的子数据源
if ([message isChatMessage]) {
[chatMessages addObject:message];
}
if ([message isGiftMessage]) {
[giftMessages addObject:message];
}
// 检查是否需要清理
if (allMessages.count > self.maxMessages) {
[self cleanupOldMessages];
}
});
}
// 同步写入版本,确保调用返回时数据已落入数组(适合随后立刻刷新快照的场景)
- (void)addMessageSync:(XPMessageItem *)message {
if (!message) return;
dispatch_sync(self.dataQueue, ^{
NSMutableArray *allMessages = (NSMutableArray *)_allMessages;
NSMutableArray *chatMessages = (NSMutableArray *)_chatMessages;
NSMutableArray *giftMessages = (NSMutableArray *)_giftMessages;
[allMessages addObject:message];
if ([message isChatMessage]) {
[chatMessages addObject:message];
}
if ([message isGiftMessage]) {
[giftMessages addObject:message];
}
if (allMessages.count > self.maxMessages) {
[self cleanupOldMessages];
}
});
}
- (void)addMessages:(NSArray<XPMessageItem *> *)messages {
if (!messages || messages.count == 0) return;
dispatch_async(self.dataQueue, ^{
NSMutableArray *allMessages = (NSMutableArray *)_allMessages;
NSMutableArray *chatMessages = (NSMutableArray *)_chatMessages;
NSMutableArray *giftMessages = (NSMutableArray *)_giftMessages;
for (XPMessageItem *message in messages) {
[allMessages addObject:message];
// 根据消息类型分发到对应的子数据源
if ([message isChatMessage]) {
[chatMessages addObject:message];
}
if ([message isGiftMessage]) {
[giftMessages addObject:message];
}
}
// 检查是否需要清理
if (allMessages.count > self.maxMessages) {
[self cleanupOldMessages];
}
});
}
- (void)removeMessage:(XPMessageItem *)message {
if (!message) return;
dispatch_async(self.dataQueue, ^{
NSMutableArray *allMessages = (NSMutableArray *)_allMessages;
NSMutableArray *chatMessages = (NSMutableArray *)_chatMessages;
NSMutableArray *giftMessages = (NSMutableArray *)_giftMessages;
[allMessages removeObject:message];
[chatMessages removeObject:message];
[giftMessages removeObject:message];
});
}
- (void)clearAllMessages {
dispatch_async(self.dataQueue, ^{
NSMutableArray *allMessages = (NSMutableArray *)_allMessages;
NSMutableArray *chatMessages = (NSMutableArray *)_chatMessages;
NSMutableArray *giftMessages = (NSMutableArray *)_giftMessages;
[allMessages removeAllObjects];
[chatMessages removeAllObjects];
[giftMessages removeAllObjects];
});
}
- (NSArray<XPMessageItem *> *)messagesForDisplayType:(NSInteger)displayType {
__block NSArray *result = nil;
dispatch_sync(self.dataQueue, ^{
switch (displayType) {
case 1: // 所有消息
result = [_allMessages copy];
break;
case 2: // 聊天消息
result = [_chatMessages copy];
break;
case 3: // 礼物消息
result = [_giftMessages copy];
break;
default:
result = [_allMessages copy];
break;
}
});
return result;
}
- (void)cleanupOldMessages {
if (_allMessages.count <= self.maxMessages) return;
// 计算需要移除的消息数量(移除一半)
NSInteger removeCount = self.maxMessages / 2;
NSArray *itemsToRemove = [_allMessages subarrayWithRange:NSMakeRange(0, removeCount)];
NSMutableArray *allMessages = (NSMutableArray *)_allMessages;
NSMutableArray *chatMessages = (NSMutableArray *)_chatMessages;
NSMutableArray *giftMessages = (NSMutableArray *)_giftMessages;
// 从所有数据源中移除这些消息
for (XPMessageItem *item in itemsToRemove) {
[allMessages removeObject:item];
[chatMessages removeObject:item];
[giftMessages removeObject:item];
}
NSLog(@"[XPMessageDataSourceManager] Cleaned up %ld old messages, remaining: %ld",
(long)removeCount, (long)_allMessages.count);
}
- (NSInteger)totalMessageCount {
__block NSInteger count = 0;
dispatch_sync(self.dataQueue, ^{
count = _allMessages.count;
});
return count;
}
- (NSInteger)messageCountForDisplayType:(NSInteger)displayType {
__block NSInteger count = 0;
dispatch_sync(self.dataQueue, ^{
switch (displayType) {
case 1: // 所有消息
count = _allMessages.count;
break;
case 2: // 聊天消息
count = _chatMessages.count;
break;
case 3: // 礼物消息
count = _giftMessages.count;
break;
default:
count = _allMessages.count;
break;
}
});
return count;
}
#pragma mark - Readonly Properties
- (NSArray<XPMessageItem *> *)allMessages {
__block NSArray *result = nil;
dispatch_sync(self.dataQueue, ^{
result = [_allMessages copy];
});
return result;
}
- (NSArray<XPMessageItem *> *)chatMessages {
__block NSArray *result = nil;
dispatch_sync(self.dataQueue, ^{
result = [_chatMessages copy];
});
return result;
}
- (NSArray<XPMessageItem *> *)giftMessages {
__block NSArray *result = nil;
dispatch_sync(self.dataQueue, ^{
result = [_giftMessages copy];
});
return result;
}
#pragma mark - Debug
- (NSString *)description {
return [NSString stringWithFormat:@"<XPMessageDataSourceManager: %p, total: %ld, chat: %ld, gift: %ld, max: %ld>",
self, (long)[self totalMessageCount], (long)[self messageCountForDisplayType:2],
(long)[self messageCountForDisplayType:3], (long)self.maxMessages];
}
@end