gpt4 book ai didi

iOS - 删除 NSMutableArray 中的对象抛出 NSRangeException

转载 作者:行者123 更新时间:2023-11-28 19:35:38 24 4
gpt4 key购买 nike

我正在使用 TCP 短连接向主机发送数据。当我想向主机发送数据时,我将实例化一个套接字,将套接字实例存储到一个数组中,然后在数据成功写入后将其删除。

我是这样做的:

- (void)connectAndSendData:(NSData *)data
{
GCDAsyncSocket *asyncSocket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)];

[_connectionDataToBeSentMap setObject:data forKey:[NSValue valueWithNonretainedObject:asyncSocket]];

NSError *error;

if(![asyncSocket connectToHost:_host onPort:TCP_COMMUNICATION_PORT withTimeout:TCP_CONNECTION_TIMEOUT error:&error])
{
NSLog(@"TCPShortConnection - failed when attempting to connect to host with IP %@", _host);
}

[_connectionList addObject:asyncSocket];
}

我会在写入数据后立即断开套接字。因此连接将在之后被删除:

- (void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError *)err
{
[_connectionList removeObject:sock];

if(err.code == GCDAsyncSocketConnectTimeoutError)
{
// NSLog(@"TCPShortConnection - on connection timed out");

[_delegate onTCPShortConnectionTimedOut];
}

else
{
// NSLog(@"TCPShortConnection - on disconnection of socket with host %@", _host);
}
}

这一行 [_connectionList removeObject:sock]; 抛出 NSRangeException。我不知道为什么。因为我通过删除空数组中不存在的对象进行了测试,所以没有抛出此类异常。

这是日志:

*** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayM objectAtIndex:]: index 1 beyond bounds [0 .. 0]'
*** First throw call stack:
(0x258d9b0b 0x25096dff 0x257ea6d3 0x257ff033 0xfae43 0x1ca94d 0x4ccba7 0x4d8eff 0x4d87f1 0x2560ae0d 0x2560a9fc)
libc++abi.dylib: terminating with uncaught exception of type NSException

截图:

enter image description here

编辑:

请注意这不是 100% 发生的。

最佳答案

猜测:您正在从不同的线程访问您的 NSMutableArray

解释:

  1. NSMutableArray 不是线程安全的,并发读写也不安全 - 如果您从 GCD 并发队列访问数组可能会发生这种情况。

  2. GCDAsyncSocket 顾名思义使用 GCD。特别是委托(delegate)调用在用户设置的 GCD 队列上调度,并且该队列可以是并发的。

  3. 您正在将全局并发队列之一设置为委托(delegate)队列。

解决方案:您应该首先确定您是否应该使用数组,我们无法为您确定。如果您需要数组,那么它需要是线程安全的。一个简单的方法是:

  1. 创建数组时,还要为该数组创建一个顺序 GCD 队列。

  2. 要执行从数组中读取的数组方法,请在数组的顺序队列上执行同步 分派(dispatch)。您可以使用 __block 变量返回分派(dispatch) block 的结果。

  3. 要对数组执行写入操作,请对数组队列使用异步分派(dispatch)。

这个简单的模型确保数组上的两个操作不会同时发生,并且所有读取和写入都按照它们被分派(dispatch)的顺序发生。

正如我在开始时所说,我猜并发访问数组是你的问题,你需要自己确定。如果是这样,应该修复它。

HTH

关于iOS - 删除 NSMutableArray 中的对象抛出 NSRangeException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39303044/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com