用“@synchronized”包装 NSArray 操作,仍然会崩溃

Wrapping NSArray manipulations with '@synchronized', still crash

我有以下 class,其中我有几种使用 cachedRequests 数组

进行操作的方法

MyClass.h

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

MyClass.m

@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;
      }
    }

问题是:


崩溃详情:

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

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

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

@implementation MyClass
{
    NSMutableArray *cachedRequests;
}

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

HTH