Ich habe gelegentlich einen Absturz in einer freigegebenen App und von Absturzberichten wissen, die Zeile bei Auftreten und Art des Absturzes - EXC_BAD_ACCESS (SIGSEGV) KERN_INVALID_ADDRESS - aber ich weiß nicht wie Der Speicher könnte ungültig werden, da die Lebensdauer des Objekts, auf das verwiesen wird, die Lebensdauer der App ist und nicht gelöscht wird, wenn die App nicht beendet wird. Wenn also der Absturz nicht auf den gelöschten Speicher zurückzuführen ist (weil dieser Speicher nicht gelöscht wird), welche anderen Gründe könnte es für die EXC_BAD_ACCESS in dieser speziellen Situation geben?EXC_BAD_ACCESS KERN_INVALID_ADDRESS aber Speicher wird nicht gelöscht
Hier ist der Code:
@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()
in einem Thread erstellt und aufgefüllt wird und wenn findAddress()
aufgerufen wird, bevor das dann gleich Null und nur Null sein würde, so der Aufruf von (self.cityAndStateDictionary)[key]
in Findaddress wäre cityAndStateDictionary abgeschlossen . Das cityAndStateDictionary
Objekt ist nicht wird überall gelöscht, daher sollte der Absturz nicht auf den Zugriff auf gelöschten Speicher zurückzuführen sein.
Welchen Grund könnte es für den Absturz geben?
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
Ich würde mit einem Problem von gleichzeitigen Anrufen gehen ... Einen Async-Aufruf in der "-init", ich glaube nicht, dass das empfohlen wird. Ich würde stattdessen einen Block auf "findAddress" erstellen und dasselbe machen, wie wir das Bild in UITableView laden. – Larme
Es ist kein Problem, einen asynchronen Prozess in einer 'init' zu starten; es ist oft für teure Initialisierungsprozesse getan. Sie haben jedoch Recht, dass dies höchstwahrscheinlich ein Nebenläufigkeitsproblem ist. – bbum