用"@synchronized"包装NSArray操作,仍然崩溃



我有以下类,其中我有几个使用数组操作的方法cachedRequests

MyClass.h

@interface MyClass : NSObject {
NSMutableArray *cachedRequests;    
}
+(MyClass*) instance; //Singleton

我的班级

@interface MyClass ()
- (void) sendFromCache:(CacheData*)data;
@end
@implementation MyClass
static MyClass *sharedSingleton = nil;
+(MyClass*) instance{
@synchronized(self) {
if(sharedSingleton == nil)
sharedSingleton = [[super allocWithZone:NULL] init];
}
return sharedSingleton;
}
- (void) initialize 
{ 
cachedRequests = nil;
}
- (void) processCache
{   
cachedRequests = [self getCachedRequests];
}    
- (void) sendNext
{       
@synchronized (self)
{
if (cachedRequests != nil && [cachedRequests count] == 0){
return;
}
CacheData *data = [cachedRequests objectAtIndex:0]; // <-- here I get Crash 

if (data != nil) {
[cachedRequests removeObject:requestData];
}
}
}

@end

看起来当我打电话时:CacheData *data = [cachedRequests objectAtIndex:0];其他一些线程重置cachedRequests,我得到了这个崩溃。

所以我所做的是:

- (void) initialize 
{ 
@synchronized (self){
cachedRequests = nil;
}
}

问题是:

  • 够了吗?我需要为cachedRequests = [self getCachedRequests];添加@synchronized (self)
  • 改用:@synchronized (cachedRequests)是好习惯吗?

崩溃详细信息:

2   CoreFoundation                  0x18595af68 -[__NSArrayM objectAtIndex:] + 240 (NSArray.m:410)
3   living                          0x100c56a1c -[RequestCache sendNext] + 168

您的变量cachedRequests是一个全局变量,由MyClass的所有实例共享,因此不同的意图在不同的self对象上同步以访问同一数组 - 这很容易成为崩溃的根源。

您可能打算通过在大括号内声明实例变量来声明它:

@implementation MyClass
{
NSMutableArray *cachedRequests;
}

正如您所怀疑的那样,您还应该保护对变量的每次访问。

呵呵

最新更新