2014-01-15 80 views
3

在我的应用程序中,我正在访问和更改多线程的可变数组。在开始时,当我试图访问objectAtIndex的对象时,因为索引超出了界限(该索引处的对象已经从另一个线程中的数组中移除),因此崩溃了。我在网上搜索如何解决这个问题上,我决定尝试这个solution。我做了一个类NSMutableArray属性,看下面的代码:NSMutableArray线程安全

@interface SynchronizedArray() 
@property (retain, atomic) NSMutableArray *array; 
@end 

@implementation SynchronizedArray 

- (id)init 
{ 
    self = [super init]; 
    if (self) 
    { 
     _array = [[NSMutableArray alloc] init]; 
    } 
    return self; 
} 

-(id)objectAtIndex:(NSUInteger)index 
{ 
    @synchronized(_array) 
    { 
     return [_array objectAtIndex:index]; 
    } 
} 

-(void)removeObject:(id)object 
{ 
    @synchronized(_array) 
    { 
     [_array removeObject:object]; 
    } 
} 

-(void)removeObjectAtIndex:(NSUInteger)index 
{ 
    @synchronized(_array) 
    { 
     [_array removeObjectAtIndex:index]; 
    } 
} 

-(void)addObject:(id)object 
{ 
    @synchronized(_array) 
    { 
     [_array addObject:object]; 
    } 
} 

- (NSUInteger)count 
{ 
    @synchronized(_array) 
    { 
     return [_array count]; 
    } 
} 

-(void)removeAllObjects 
{ 
    @synchronized(_array) 
    { 
     [_array removeAllObjects]; 
    } 
} 

-(id)copy 
{ 
    @synchronized(_array) 
    { 
     return [_array copy]; 
    } 
} 

,我使用这个类来代替旧的可变数组,但该应用程序仍在这条线上崩溃:return [_array objectAtIndex:index];我也试过这种方法NSLock,但没有运气。我做错了什么以及如何解决这个问题?

+1

您是否正在同步对[[NSMutableArray count]]的访问(以及对数组的每次访问)? – trojanfoe

+0

是的,所有使用的方法:计数,removeObjectAtIndex,addObject等 –

+0

我编辑的问题,并添加了整个班级代码 –

回答

7

我相信这个解决方案很差。考虑这个:

  1. 线程#1调用count并被告知有4个对象在数组中。
  2. 数组未被同步。
  3. 线程#2调用数组上的removeObjectAtIndex:2
  4. 数组未被同步。
  5. 线程#1调用objectAtIndex:3并发生错误。

相反,您需要一个更高级别的锁定机制,其中锁定在步骤1和5的数组周围,并且线程#2无法删除这些步骤之间的对象。

+0

@Euroboy这是一个更好的SO问题使用:http://stackoverflow.com/questions/17091389/nsmutablearray-collection-and-synchronized-blocks – trojanfoe

+0

是的,我在...之前看过这个问题,我从那里得到灵感。然而,我也尝试了GCD方法,但问题仍然存在......我很困惑:( –

+0

我离开了一个类的方法,并直接使用'@ synchronized'到我的'NSMutableArray',现在一切正常。 –

4

您需要保护(使用@synchronized)基本上所有的阵列用法。目前,您只能防止多个线程同时将对象从阵列中取出。但是,对于你描述的并发修改和变异的情况,你没有任何保护。

问问你自己为什么要修改多线程的数组 - 你应该这样做还是只使用一个线程?使用不同的数组实现或使用总是切换到主线程以进行请求的修改的包装类可能更容易。