EXC_BAD_ACCESS KERN_INVALID_ADDRESS但内存未被删除

时间:2017-07-24 16:24:01

标签: ios objective-c

我在发布的应用程序中偶尔发生崩溃,并且从崩溃报告中知道它发生的线路和崩溃类型 - EXC_BAD_ACCESS(SIGSEGV)KERN_INVALID_ADDRESS - 但我不知道内存如何因为生命周期而变得无效被引用的对象是应用程序的生命周期,除非应用程序终止,否则不会被删除。因此,如果崩溃不是由于访问已删除的内存(因为该内存未被删除),那么在这种特殊情况下,EXC_BAD_ACCESS可能会有什么其他原因?

以下是代码:

 @interface Model()
 @property (strong, nonatomic)   NSMutableDictionary*  cityAndStateDictionary;
 @end


- (NSString*) findAddress: (NSString*) key
{
    if (key == nil)
    {
        return nil;
    }
    NSString* cityAndState = (self.cityAndStateDictionary)[key]; // Crash here
}



@implementation Model
- (id) init
{
    self = [super init];
    if (self)
    {
        dispatch_async(modelQueue(), ^{
            [self readCityAndStateData];
        });
    }
}


- (void) readCityAndStateData
{
    NSBundle* bundle = [NSBundle bundleForClass:[Model class]];
    NSString *filePath = [bundle pathForResource:@"CityState" ofType:@"json"];
    NSData *data = [NSData dataWithContentsOfFile:filePath];
    NSError* __autoreleasing  nserror;
    NSDictionary* jsonParser = [NSJSONSerialization JSONObjectWithData: data
                                                               options: NSJSONReadingAllowFragments
                                                                 error: &nserror];
    if (nserror == nil)
    {
        self.cityAndStateDictionary = [[NSMutableDictionary alloc] init];
        for (NSDictionary *item in jsonParser)
        {
            // create value object
            (self.cityAndStateDictionary)[key] = value;
        }
    }
}
正在创建

readCityAndStateData()并在一个线程中填充,如果在完成之前调用findAddress(),则cityAndStateDictionary将为nil,因此在findAddress中对(self.cityAndStateDictionary)[key]的调用将为零。 cityAndStateDictionary对象被删除,因此崩溃不应该是因为访问已删除的内存。

崩溃的原因是什么?

Exception Type:  EXC_BAD_ACCESS (SIGSEGV)
Exception Subtype: KERN_INVALID_ADDRESS at 0x000000010624ae60
Termination Signal: Segmentation fault: 11
Termination Reason: Namespace SIGNAL, Code 0xb
Terminating Process: exc handler [0]
Triggered by Thread:  0

Thread 0 name:
Thread 0 Crashed:
0   CoreFoundation                  0x000000018356446c -[__NSDictionaryM objectForKey:] + 108 (NSDictionary.m:543)
1   CoreFoundation                  0x0000000183564450 -[__NSDictionaryM objectForKey:] + 80 (NSDictionary.m:538)
2   Name Of May App                 0x0000000100021f38 -[Model findAddress:] + 268 (Model.m:590)
3   Name Of May App                 0x00000001000beb78 _TTSf4g_n_n___TFC14Caller_Name_ID28BlockedNumbersViewController17formatBlockedCellfT6callerCS_6Caller3rowSi_CS_11BlockedCell + 1688 (BlockedNumbersViewController.swift:395)
4   Name Of May App                 0x00000001000bf1b0 _TTSf4g_g_n___TFC14Caller_Name_ID28BlockedNumbersViewController9tableViewfTCSo11UITableView12cellForRowAtV10Foundation9IndexPath_CSo15UITableViewCell + 528 (BlockedNumbersViewController.swift:0)
5   Name Of May App                 0x00000001000ba01c _TToFC14Caller_Name_ID28BlockedNumbersViewController9tableViewfTCSo11UITableView12cellForRowAtV10Foundation9IndexPath_CSo15UITableViewCell + 76 (BlockedNumbersViewController.swift:0)
6   UIKit                           0x0000000189af5aa8 -[UITableView _createPreparedCellForGlobalRow:withIndexPath:willDisplay:] + 688 (UITableView.m:10803)
7   UIKit                           0x0000000189af5cc0 -[UITableView _createPreparedCellForGlobalRow:willDisplay:] + 80 (UITableView.m:10848)
8   UIKit                           0x0000000189ae33c4 -[UITableView _updateVisibleCellsNow:isRecursive:] + 2152 (UITableView.m:2273)
9   UIKit                           0x0000000189afacb0 -[UITableView _performWithCachedTraitCollection:] + 120 (UITableView.m:12556)
10  UIKit                           0x0000000189893774 -[UITableView layoutSubviews] + 176 (UITableView.m:7390)
11  UIKit                           0x00000001897adf98 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 1200 (UIView.m:14232)
12  QuartzCore                      0x000000018699e274 -[CALayer layoutSublayers] + 148 (CALayer.mm:8937)
13  QuartzCore                      0x0000000186992de8 CA::Layer::layout_if_needed(CA::Transaction*) + 292 (CALayer.mm:8817)
14  QuartzCore                      0x0000000186992ca8 CA::Layer::layout_and_display_if_needed(CA::Transaction*) + 32 (CALayer.mm:2345)
15  QuartzCore                      0x000000018690e34c CA::Context::commit_transaction(CA::Transaction*) + 252 (CAContextInternal.mm:1689)
16  QuartzCore                      0x00000001869353ac CA::Transaction::commit() + 504 (CATransactionInternal.mm:420)
17  QuartzCore                      0x0000000186935e78 CA::Transaction::observer_callback(__CFRunLoopObserver*, unsigned long, void*) + 120 (CATransactionInternal.mm:793)
18  CoreFoundation                  0x000000018362c9a8 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 32 (CFRunLoop.c:1802)
19  CoreFoundation                  0x000000018362a630 __CFRunLoopDoObservers + 372 (CFRunLoop.c:1898)
20  CoreFoundation                  0x000000018362aa7c __CFRunLoopRun + 956 (CFRunLoop.c:2849)
21  CoreFoundation                  0x000000018355ada4 CFRunLoopRunSpecific + 424 (CFRunLoop.c:3113)
22  GraphicsServices                0x0000000184fc5074 GSEventRunModal + 100 (GSEvent.c:2245)
23  UIKit                           0x0000000189815f74 UIApplicationMain + 208 (UIApplication.m:4089)
24  Name Of May App                 0x000000010003a8b4 main + 56 (Database.swift:17)
25  libdyld.dylib                   0x000000018256959c start + 4

1 个答案:

答案 0 :(得分:1)

可变字典不是线程安全的。

您需要确保只从单个线程访问每个字典。

请注意dispatch_async中的init不是问题。但在这种情况下不太可能有必要。您是否测量了readCityAndStates方法的执行时间,以确定它是否确实是性能问题?同样,您应该将其存储为二进制格式,而不是将该静态资源存储为JSON。这将解析得更快,并且更重要的是,会减少应用包的大小。