我正在使用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
屏幕截图:
编辑:
请不要以为这不是100%发生。
最佳答案
猜猜:您正在从不同的线程访问您的NSMutableArray
说明:NSMutableArray
不是线程安全的,并发读写也不安全-如果从GCD并发队列访问数组,可能会发生这种情况。
顾名思义,GCDAsyncSocket
使用GCD。特别是,委托调用是在用户设置的GCD队列上调度的,并且此队列可以是并发的。
您正在将全局并发队列之一设置为委托队列。
解决方案:您应该首先确定是否应该使用数组,但我们无法为您确定。如果需要数组,则它必须是线程安全的。一种简单的方法是:
创建阵列时,还要为此阵列创建一个顺序的GCD队列。
要执行从数组读取的数组方法,请对数组的顺序队列执行同步调度。您可以使用__block
变量从分派的块中返回结果。
要对阵列执行写操作,请使用异步分派到阵列的队列。
这个简单的模型可确保在阵列上不能同时发生两个操作,并且所有读取和写入均以分派的顺序进行。
正如我在开始时所说的,我猜测对数组的并发访问是您的问题,您需要确定自己。如果是这样,应该修复它。
高温超导
关于ios - iOS-删除NSMutableArray中的对象会引发NSRangeException,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/39303044/