255 lines
7.6 KiB
Mathematica
255 lines
7.6 KiB
Mathematica
![]() |
//
|
|||
|
// 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
|