2017-12-07 55 views
0

時々、EXC_BAD_ADDRESSエラーログで致命的なエラーが発生します。これを解決するには(Objective-CのEXC_BAD_ADDRESS)?

私のコードの原因は何ですか?このクラスは、他の多くのクラスから非同期的に使用されている

クラッシュログ

0. Crashed: GGMutableDictionary Isolation Queue 
0 libobjc.A.dylib    0x184e2c150 objc_msgSend + 16 
1 CoreFoundation     0x1862e0d04 -[NSDictionary descriptionWithLocale:indent:] + 916 
2 CoreFoundation     0x1862e0dac -[NSDictionary descriptionWithLocale:indent:] + 1084 
3 Foundation      0x186da35a4 _NSDescriptionWithLocaleFunc + 76 
4 CoreFoundation     0x1863788bc __CFStringAppendFormatCore + 8440 
5 CoreFoundation     0x18637678c _CFStringCreateWithFormatAndArgumentsAux2 + 244 
6 Foundation      0x186da3418 +[NSString stringWithFormat:] + 68 
7 app       0x10019f4b8 -[TinyDB saveAsync] + 4296963256 
8 app       0x10019c86c __26-[TinyDB putString:value:]_block_invoke + 4296951916 
9 libdispatch.dylib    0x18526e9a0 _dispatch_client_callout + 16 
10 libdispatch.dylib    0x18527bee0 _dispatch_barrier_sync_f_invoke + 84 
11 app       0x10019c7e0 -[TinyDB putString:value:] + 4296951776 

ソースファイル

。 このクラスはスレッドセーフである必要があります。しかし、EXC_BAD_ADDRESSの致命的なエラーは、saveAsyncメソッドで発生します。 weakDictionaryRefまたはisolationQueueの変数が割り当て解除されていると思います。私はこの問題を解決したい。このコードで私は何を修正すべきですか? ありがとうございました。

TinyDB.hファイル

@interface TinyDB : NSObject 

@property (nonatomic, retain) NSString * docPath; 
// @property (nonatomic, retain) NSMutableDictionary * dictionary; 
@property (nonatomic, retain) NSFileManager * fileManager; 
@property (nonatomic, retain) NSString * dir; 
@property (nonatomic, assign) BOOL flagWrite; 
- (instancetype)initWithFile:(NSString *)file; 
- (NSString *)getDocPath; 
- (void)putDouble:(NSString *)key value:(double)value; 
- (void)putInt:(NSString *)key value:(NSInteger)value; 
- (void)putMutableArray:(NSString *)key value:(NSMutableArray *)value; 
- (void)putString:(NSString *)key value:(NSString *)value; 
- (void)putTinyDB:(NSString *)key value:(TinyDB *)value; 
- (void)putLong:(NSString *)key value:(NSInteger)value; 
- (void)putBool:(NSString *)key value:(BOOL)value; 
- (void)putDictionary:(NSString *)key value:(NSDictionary *)value; 
- (id)get:(NSString *)key; 
- (NSMutableArray *)getMutableArray:(NSString *)key; 
- (BOOL)has:(NSString *)key; 
- (void)saveAsync; 
- (void)save; 
- (NSString *)jsonString; 
- (NSString *)stringify:(id)obj; 
- (NSString *)getSet:(id)value; 
- (NSString *)getPairSet:(NSString *)key value:(id)value; 
- (NSMutableDictionary*)getMutableDictionary:(NSString*)key; 
- (NSString *)getString:(NSString *)key; 
- (BOOL)getBool:(NSString*)key; 
- (NSArray *)allKeys; 
- (void)removeObjectForKey:(NSString*)key; 
@end 

TinyDB.mファイル

@implementation TinyDB 
{ 
@private dispatch_queue_t isolationQueue_; 
@private __strong NSMutableDictionary * _myDictionary; 
} 
@synthesize docPath=docPath,fileManager=fileManager,dir=dir,flagWrite=flagWrite; 
BOOL flagOnSave = false; 
BOOL flagWrite = true; 
NSString* dir; 
NSString* docPath = @""; 
NSLock* _dicLock=nil; 
NSFileManager* fileManager; 
__weak id _weakDictionaryRef; 

-(id)initWithFile:(NSString *)file{ 
    self = [super init]; 
    docPath = file; 
    // ########################################## 
    isolationQueue_ = dispatch_queue_create([@"GGMutableDictionary Isolation Queue" UTF8String], DISPATCH_QUEUE_CONCURRENT); 
    // ########################################## 
    fileManager = [NSFileManager defaultManager]; 
    dir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, true) firstObject]; 
    dir = [NSString stringWithFormat:@"%@/myapp/",dir]; 
    BOOL flagFileExist = [fileManager fileExistsAtPath:[[NSString alloc] initWithFormat:@"%@/%@.myapp",dir,docPath]]; 
    _myDictionary = [[NSMutableDictionary alloc] init]; 
    if(flagFileExist){ 
     [BSDebugger log:[NSString stringWithFormat:@"DEBUG_myapp_CONFIG : File Found!!! %@ --> ",file]]; 
     @try{ 
      NSMutableDictionary* dic = [[NSMutableDictionary alloc] initWithContentsOfFile:[[NSString alloc] initWithFormat:@"%@/%@.myapp",dir,docPath]]; 
      _myDictionary = [[NSMutableDictionary alloc] initWithDictionary:dic]; 
     }@catch(NSException * e){ 
      _myDictionary = [[NSMutableDictionary alloc] init]; 
     }@finally{ 
     } 
    }else{ 
     [BSDebugger log:[NSString stringWithFormat:@"DEBUG_myapp_CONFIG : File Not Found!!!--> %@ ",file]]; 
     _myDictionary = [[NSMutableDictionary alloc] init]; 
    } 
    _weakDictionaryRef = _myDictionary; 
    [self saveAsync]; 
    return self; 
} 
-(void)putString:(NSString*)key value:(NSString*)value{ 
    dispatch_barrier_sync(isolationQueue_, ^{ 
     if(value == nil){ 
      return; 
     } 
     @try{ 
      [_myDictionary setObject:value forKey:key]; 
     }@catch(NSException* e){ 
      NSMutableDictionary* buff = [[NSMutableDictionary alloc] initWithDictionary:_myDictionary]; 
      _myDictionary = buff; 
      _weakDictionaryRef = _myDictionary; 
      dispatch_barrier_sync(isolationQueue_, ^{ 
       [_myDictionary setObject:value forKey:key]; 
      }); 
     }@finally{ 
     } 
     [self saveAsync]; 
    }); 
} 

- (void)putDouble:(NSString *)key value:(double)value{ 
    dispatch_barrier_sync(isolationQueue_, ^{ 
     [_myDictionary setObject:[[NSNumber alloc] initWithDouble:value] forKey:key]; 
     [self saveAsync]; 
    }); 
} 
- (void)putInt:(NSString *)key value:(NSInteger)value{ 
    dispatch_barrier_sync(isolationQueue_, ^{ 
     @try{ 
      [_myDictionary setObject:[[NSNumber alloc] initWithInteger:value] forKey:key]; 
     }@catch(NSException* e){ 
      NSMutableDictionary* buff = [[NSMutableDictionary alloc] initWithDictionary:_myDictionary]; 
      _myDictionary = buff; 
      _weakDictionaryRef = _myDictionary; 
      [_myDictionary setObject:[[NSNumber alloc] initWithInteger:value] forKey:key]; 
     }@finally{ 
     } 
     [self saveAsync]; 
    }); 
} 
- (void)putMutableArray:(NSString *)key value:(NSMutableArray *)value{ 
    dispatch_barrier_sync(isolationQueue_, ^{ 
     if(key != nil && value != nil){ 
      [_myDictionary setObject:value forKey:key]; 
      [self saveAsync]; 
     } 
    }); 
} 
- (void)putTinyDB:(NSString *)key value:(TinyDB *)value{ 
    dispatch_barrier_sync(isolationQueue_, ^{ 
     TinyDB* db = value; 
     NSString* docuPath = [db getDocPath]; 
     @try{ 
      [_myDictionary setObject:docuPath forKey:key]; 
     }@catch(NSException* e){ 
      NSMutableDictionary* buff = [[NSMutableDictionary alloc] initWithDictionary:_myDictionary]; 
      _myDictionary = buff; 
      _weakDictionaryRef = _myDictionary; 
      dispatch_barrier_sync(isolationQueue_, ^{ 
       [_myDictionary setObject:docuPath forKey:key]; 
      }); 
     }@finally{ 

     } 
     [self saveAsync]; 
    }); 
} 
- (void)putLong:(NSString *)key value:(NSInteger)value{ 
    dispatch_barrier_sync(isolationQueue_, ^{ 
     [_myDictionary setObject:[[NSNumber alloc] initWithInteger:value] forKey:key]; 
     [self saveAsync]; 
    }); 
} 
- (void)putBool:(NSString *)key value:(BOOL)value{ 
    dispatch_barrier_sync(isolationQueue_, ^{ 
     [_myDictionary setObject:[[NSNumber alloc] initWithBool:value] forKey:key]; 
     [self saveAsync]; 
    }); 
} 
- (void)putDictionary:(NSString *)key value:(NSDictionary *)value{ 
    dispatch_barrier_sync(isolationQueue_, ^{ 
     [_myDictionary setObject:value forKey:key]; 
     [self saveAsync]; 
    }); 
} 
-(void)removeObjectForKey:(NSString*)key{ 
    dispatch_barrier_sync(isolationQueue_, ^{ 
     if(_myDictionary != nil && [_myDictionary objectForKey:key] != nil){ 
      [_myDictionary removeObjectForKey:key]; 
     } 
    }); 
} 
-(void) save{ 
    dispatch_barrier_sync(isolationQueue_, ^{ 
     @try { 
      // NSLog([NSString stringWithFormat:@"writeToFile Error : orgPath = %@/%@.myapp/%@",dir,docPath, self.dictionary ]); 
      // NSMutableDictionary* nsDic = self.dictionary; 
      if(_myDictionary != nil){ 
       NSDictionary * _dictionary = 
       (__bridge NSDictionary *)(CFPropertyListCreateDeepCopy(kCFAllocatorDefault, 
                     (__bridge CFPropertyListRef)(_myDictionary), 
                     kCFPropertyListImmutable)); 
       if(_dictionary != nil){ 
        [_dictionary writeToFile:[[NSString alloc] initWithFormat:@"%@/%@.myapp",dir,docPath] atomically: false]; 
       } 
      } 
     }@catch (NSException *exception) { 
      _myDictionary = [[NSMutableDictionary alloc] initWithDictionary:_myDictionary]; 
      _weakDictionaryRef = _myDictionary; 
     }@finally { 
     } 
    }); 
} 
// ################################################################ 
// normal function 
- (NSString *)jsonString{ 
    __block NSString* buff = @""; 
    dispatch_barrier_sync(isolationQueue_, ^{ 
     if(_myDictionary != nil){ 
      NSDictionary * _dictionary = nil; 
      // dispatch_barrier_sync(isolationQueue_, ^{ 
      _dictionary = (__bridge NSDictionary *)(CFPropertyListCreateDeepCopy(kCFAllocatorDefault, 
                       (__bridge CFPropertyListRef)(_myDictionary), 
                       kCFPropertyListImmutable)); 
      if(_dictionary != nil){ 
       buff = [self stringify:_dictionary]; 
      } 
     }else{ 
      NSLog(@"buff = [self stringify:_myDictionary]; is nil "); 
     } 

    }); 
    return buff; 
} 
- (NSString *)stringify:(id)obj{ 
    if([obj isKindOfClass:[NSDictionary class]]){ 
     int idx = 0; 
     NSString* buff = @"{"; 
     if(obj != nil){ 
      NSDictionary* dic = [NSDictionary dictionaryWithDictionary:obj]; //obj; 
      for(NSString* key in dic){ 
       id value = [dic objectForKey:key]; 
       if(idx != 0){ 
        buff = [[NSString alloc] initWithFormat:@"%@%@",buff,@","]; 
       } 
       buff = [[NSString alloc] initWithFormat:@"%@%@",buff,[self getPairSet:key value:value]]; 
       idx++; 
      } 
     } 
     buff = [[NSString alloc] initWithFormat:@"%@%@",buff,@"}"]; 
     return buff; 
    }else if([obj isKindOfClass:[NSArray class]]){ 
     int idx = 0; 
     NSString* buff = @"["; 
     if(obj != nil){ 
      NSMutableArray* _a = [[NSMutableArray alloc] init]; 
      for(int ai = 0; ai < [obj count]; ai++){ 
       if([obj objectAtIndex:ai] != nil){ 
        [_a addObject:[obj objectAtIndex:ai]]; 
       } 
      } 
      NSArray* arr = [NSArray arrayWithArray:_a]; //obj; 
      for(id value in arr){ 
       if(idx != 0){ 
        buff = [[NSString alloc] initWithFormat:@"%@%@",buff,@","]; 
       } 
       buff = [[NSString alloc] initWithFormat:@"%@%@",buff,[self getSet:value]]; 
       idx++; 
      } 
     } 
     buff = [[NSString alloc] initWithFormat:@"%@%@",buff,@"]"]; 
     return buff; 
    }else{ 
     return [self getSet:obj]; 
    } 
} 
- (NSString *)getSet:(id)value{ 
    NSString* buff = @""; 
    if([value isKindOfClass:[NSString class]]){ 
     buff = [[NSString alloc] initWithFormat:@"%@\"%@\"",buff,value]; 
    }else if([value isKindOfClass:[NSNumber class]]){ 
     NSNumber* val = value; 
     buff = [[NSString alloc] initWithFormat:@"%@%@",buff,[val stringValue]]; 
    }else{ 
     buff = [[NSString alloc] initWithFormat:@"%@%@",buff,[self stringify:value]]; 
    } 
    return buff; 
} 
- (NSString *)getPairSet:(NSString *)key value:(id)value{ 
    NSString* buff = @""; 
    if([value isKindOfClass:[NSString class]]){ 
     buff = [[NSString alloc] initWithFormat:@"%@\"%@\":\"%@\"",buff,key,value]; 
    }else if([value isKindOfClass:[NSNumber class]]){ 
     buff = [[NSString alloc] initWithFormat:@"%@\"%@\":%@",buff,key,[value stringValue]]; 
    }else{ 
     buff = [[NSString alloc] initWithFormat:@"%@\"%@\":%@",buff,key,[self stringify:value]]; 
    } 
    return buff; 
} 
-(NSMutableDictionary*)getMutableDictionary:(NSString*)key{ 
    NSMutableDictionary* dic = [[NSMutableDictionary alloc] init]; 
    id obj = [_myDictionary objectForKey:key]; 
    if(obj != nil){ 
     dic = [[NSMutableDictionary alloc] initWithDictionary:obj]; 
    } 
    return dic; 
} 
-(NSArray *)allKeys{ 
    __block NSArray* arr = nil; 
    dispatch_barrier_sync(isolationQueue_, ^{ 
     if(_myDictionary != nil){ 
      arr = [_myDictionary allKeys]; 
     } 
    }); 
    return arr; 
} 
- (NSString *)getDocPath{ 
    return docPath; 
} 
- (id)get:(NSString *)key{ 
    __block id _obj = nil; 
    dispatch_barrier_sync(isolationQueue_, ^{ 
     _obj = [_myDictionary objectForKey:key]; 
    }); 
    return _obj; 
} 
- (NSString *)getString:(NSString *)key{ 
    __block NSString* returnStr = @""; 
    dispatch_barrier_sync(isolationQueue_, ^{ 
     if([_myDictionary objectForKey:key]==nil){ 
      returnStr = @""; 
     } 
     if([[_myDictionary objectForKey:key] isKindOfClass:[NSString class]]){ 
      returnStr = [_myDictionary objectForKey:key]; 
     }else{ 
      returnStr = @""; 
     } 
    }); 
    return returnStr; 
} 
- (BOOL)getBool:(NSString*)key{ 
    __block BOOL flag = false; 
    dispatch_barrier_sync(isolationQueue_, ^{ 
     if([_myDictionary objectForKey:key]==nil){ 
      flag = NO; 
     } 
     if([[_myDictionary objectForKey:key] isKindOfClass:[NSNumber class]]){ 
      NSNumber* boolValue = [_myDictionary objectForKey:key]; 
      if([boolValue boolValue] == YES){ 
       flag = YES; 
      }else{ 
       flag = NO; 
      } 
     }else{ 
      flag = NO; 
     } 
    }); 
    return flag; 
} 
- (NSMutableArray *)getMutableArray:(NSString *)key{ 
    __block NSMutableArray* _arr = nil; 
    dispatch_barrier_sync(isolationQueue_, ^{ 
     _arr = [_myDictionary objectForKey:key]; 
    }); 
    return _arr; 
} 
- (BOOL)has:(NSString *)key{ 
    __block BOOL flag = false; 
    dispatch_barrier_sync(isolationQueue_, ^{ 
     if([_myDictionary objectForKey:key] != nil){ 
      flag = true; 
     }else{ 
      flag = false; 
     } 
    }); 
    return flag; 
} 
// ######################### 
// save function 
int flagTest = 0; 
bool mark = 0; 
NSTimer* saveTimer = nil; 
-(void)saveAsync{ 
    @try { 
     [BSDebugger log:[NSString stringWithFormat:@"_weakDictionaryRef : %@ ",_weakDictionaryRef ]]; 
     if(_myDictionary != nil){ 
      if(_weakDictionaryRef != nil){ 
       NSDictionary * _dictionary = nil; 
       _dictionary = (__bridge NSDictionary *)(CFPropertyListCreateDeepCopy(kCFAllocatorDefault, 
                        (__bridge CFPropertyListRef)(_myDictionary), 
                        kCFPropertyListImmutable)); 
       @try{ 
        flagOnSave = true; 
        UIBackgroundTaskIdentifier taskID = [myappCore beginBackgroundUpdateTask]; 
        flagWrite = false; 
        NSString* orgPath = [[NSString alloc] initWithFormat:@"%@/%@.myapp",dir,docPath ]; 
        @try { 
         if(_dictionary != nil){ 
          [_dictionary writeToFile:orgPath atomically:YES]; 
         } 
        }@catch (NSException *exception) { 
         [BSDebugger log:[NSString stringWithFormat:@"DEBUG_myapp_TINYDB : %@",[exception callStackSymbols]]]; 
        }@finally { 
        } 
        flagWrite = true; 
        flagOnSave = false; 
        [myappCore endBackgroundUpdateTask:taskID]; 
       }@catch (NSException *exceptionMain) { 
        [BSDebugger log:[NSString stringWithFormat:@"DEBUG_myapp_TINYDB : %@",[exceptionMain callStackSymbols]]]; 
       }@finally { 
        _dictionary = nil; 
       } 
       return; 
       // }); 
      } 
     } 
    }@catch (NSException *exception) { 
    }@finally { 
     // [_dicLock unlock]; 
    } 
} 
@end 

答えて

0

いくつかのアイデア:ゾンビの

電源を入れます(How to enable NSZombie in Xcode)。そうしたときにクラッシュの原因となったオブジェクトに関する詳細情報が表示されます。

エラーを任意に発生させることができる場合は、先頭にブレークポイントを設定してsaveAsyncを実行します。

stringWithFormatコールを何らかの形で変更すると、割り当てが解除された可能性のあるものは参照されず、問題が解決しないかどうかが確認されます。もしそうなら、あなたはその原因を知るでしょう。

私はそれは時々私はの不審なよオブジェクトでretainreleaseをオーバーライドして、いずれかのうちの印刷何かまたは私は介して放出対象である場合があります誰が見ることができるようにブレークポイントを設定するのに役立ちます見つけます。

関連する問題