![](/img/trans.png)
[英]NSMutableArray remove objectAtIndex NSRangeException IOS
[英]iOS - Removing An Object In NSMutableArray Throws NSRangeException
我正在使用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
變量從分派的塊中返回結果。
要對陣列執行寫操作,請使用異步分派到陣列的隊列。
這個簡單的模型可確保在陣列上不能同時發生兩個操作,並且所有讀取和寫入均以分派的順序進行。
正如我在開始時所說的,我猜測對數組的並發訪問是您的問題,您需要確定自己。 如果是這樣,應該修復它。
高溫超導
這里有兩種情況:
情況1:成功將對象添加到_connectionList數組中時。
[_connectionList addObject:asyncSocket];
在這種情況下,不會發生此類異常。
[_connectionList removeObject:sock];
從_connectionList數組中成功刪除該對象。
情況2:當對象未成功添加到_connectionList數組中時。
在此引發異常,
[__NSArrayM objectAtIndex:]: index 1 beyond bounds [0 .. 0]
因為該對象未成功添加到_connectionList數組中。
因此,這個問題稱為讀寫器問題 。
因為NSMutableArray不是線程安全的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.