2012-03-27 8 views
0

Ich vermute, das muss neue Funktionalität sein, da dieser Code auf meinem iOS4-Gerät fehlschlagen, funktioniert gut auf iOS5. Ich brauche das, um an beiden zu arbeiten. Ich bin noch nicht auf iOS5 umgestiegen, da ich noch iOS4 unterstützen muss, also bin ich ratlos, wie ich das umgehen kann?Holen EXC_BAD_ACCESS in iOS 4 mit dispatch_once, nicht in iOS 5

static dispatch_once_t oncePredicate; 
dispatch_once(&oncePredicate, ^{ //EXC_BAD_ACCESS 
    _sharedStoreManager = [[super allocWithZone:nil] init];    
}); 

Es ist von https://github.com/MugunthKumar/MKStoreKit/blob/master/MKStoreManager.m

+0

'dispatch_once' ist ab iOS 4.0 verfügbar. Kannst du mehr Informationen über den Absturz geben? –

+1

Können Sie uns Ihr Backtrace zeigen? –

Antwort

4

dispatch_once() mit iOS ist nicht neu 5.0, ist es schon seit 4.0. Ich benutze es die ganze Zeit in Anwendungen, die von einem meines Frameworks 4.0, wie in diesem Singleton Ziel:

+ (GPUImageOpenGLESContext *)sharedImageProcessingOpenGLESContext; 
{ 
    static dispatch_once_t pred; 
    static GPUImageOpenGLESContext *sharedImageProcessingOpenGLESContext = nil; 

    dispatch_once(&pred, ^{ 
     sharedImageProcessingOpenGLESContext = [[GPUImageOpenGLESContext alloc] init]; 
    }); 
    return sharedImageProcessingOpenGLESContext; 
} 

Von Apple's documentation:

Verfügbarkeit

Erhältlich in iOS 4.0 und später.

Ich vermute, Ihr Problem existiert innerhalb der -init Ihres _sharedStoreManager. Gibt es zum Beispiel einen Grund, warum Sie dort -allocWithZone: verwenden?

1

dispatch_onceis available, und mit dem von Ihnen geposteten Snippet ist nichts falsch.

Ich sehe zwei Probleme mit dem Rest des Codes, die beide jedoch von der Linie stamm 194. Zunächst wird der Manager init zweimal gesendet werden: einmal in dem dispatch_once Block, und dann nach, auf dieser Linie:

if(!_sharedStoreManager) { 
    static dispatch_once_t oncePredicate; 
    dispatch_once(&oncePredicate, ^{ 
     _sharedStoreManager = [[super allocWithZone:nil] init];    
    }); 

    #if TARGET_IPHONE_SIMULATOR 
    NSLog(@"You are running in Simulator MKStoreKit runs only on devices"); 
    #else 
/*194*/_sharedStoreManager = [[self alloc] init]; 

Dies ist eine schlechte Sache zu tun.

Dies und noch wichtiger ist, dass dies wie eine Endlosschleife aussieht. Linie 194 ruft dort +[MKStoreManager alloc] auf, die bei +[MKStoreManager allocWithZone:] endet, die +sharedManager wieder ruft!

+ (id)allocWithZone:(NSZone *)zone 
{ 
    return [self sharedManager]; 
} 

hätte ich nicht gedacht, dass eine solche Schleife EXC_BAD_ACCESS verursachen würde, aber ich empfehle Linie Entfernen 194; es ist falsch.

(I auch würde empfehlen, den Einzug des if Block zu befestigen.)

2

Dies wurde durch einen Fehler in meinem Code verursacht, und ich habe eine Lösung für sie gedrückt. Aktualisieren Sie Ihre Submodule. Danke an Brad Larson für die Benachrichtigung.

Verwandte Themen