2012-12-03 4 views
13

Update: Dies wurde in iOS 6.1 DP3 SDK behoben.Objekt erstellt innerhalb des Geltungsbereichs freigegeben, auch wenn außerhalb des Gültigkeitsbereichs verwendet

Ich habe einen Absturz nach dem Absturz beim Einsatz von ARC mit der Standard-Release-Build-Konfiguration (Debug scheint gut zu funktionieren) ausfindig gemacht. Das Problem tritt auf, wenn Sie ein Objekt innerhalb eines if-scope mit einer nicht konstanten Bedingung erstellen, es einer Variablen außerhalb des Bereichs zuweisen und dann nur die Variable mithilfe von Objective-C-Array- oder Dictionary-Literalen referenzieren.

Hier ist die kleinste reproduzierbar Fall ich habe es geschafft, zu finden:

void test(BOOL arg) 
{ 
    id obj = nil; 

    if (arg) { 
     obj = [NSObject new]; 
    } 

    // obj already deallocated here 
    @[obj]; 

    // but using NSArray works 
    //[NSArray arrayWithObject:obj]; 

    // @[obj] works if obj is referenced i.e. by NSLog print out 
    //NSLog(@"%@", obj); 
} 

int main(int argc, const char * argv[]) 
{ 
    @autoreleasepool { 
     test(YES); 
    } 
    return 0; 
} 

Wenn ich diese Objekte mit Zombie erstellen und ausführen aktiviert ich diese Fehlermeldung:

-[NSObject retain]: message sent to deallocated instance 0x100109100 

Wie ich kommentiert Im Code funktioniert es gut, wenn obj in einer anderen Weise referenziert wird, wie mit NSLog oder stattdessen NSArray. Habe ich missverstanden, wie Objekte mit ARC und Scopes freigegeben werden oder ist das ein Optimierungsfehler in LLVM oder Clang?

Ich verwende Xcode 4.5.2 mit Clang Version 4.1 (Tags/Apple/clang-421.11.66) (basierend auf LLVM 3.1svn). Ich kann es reproduzieren, wenn ich für x86 64 Bit für iOS-Simulator und Mac OS X baue, und ich bin mir ziemlich sicher, dass das gleiche Problem beim Erstellen von ARM auftritt, da das Problem beim Ausführen von Release Build auf einem iPhone zuerst auftrat.

Ich habe eingereicht und Fehlerbericht an Apple und erstellt open radar report.

Was, wenn überhaupt, vermisse ich?

aktualisieren, haben einige weitere Experimente:

Als Gabro den Compiler @[] auf eine [NSArray arrayWithObjects:count:] Aussage wies darauf hin, übersetzt so habe ich einige Tests:

// works 
id a[] = {obj}; 
[NSArray arrayWithObjects:a count:1]; 

// does not work 
const id *b = (id[]){obj}; 
[NSArray arrayWithObjects:b count:1]; 

// does not work 
[NSArray arrayWithObjects:(id[]){obj} count:1]; 

So ist meine Vermutung, dass dies geschieht, wenn Kombinieren von ARC und anonymen C-Arrays.

+0

+1 für die Buchung eines SSCCE –

+1

laut Apple, wenn Sie die Arrayliteral verwenden, erzeugt der Compiler die folgenden '' 'id Objekte [] = {obj}; NSUInteger count = Größe (Objekte)/Größe (ID); [NSArray arrayWithObjects: Anzahl der Objekte: Anzahl]; '' ' Ich frage mich, ob es einen Fehler aufgrund der durchgehenden Spiel C-Arrays –

+1

Sehr seltsam ist. Ich würde es einen Fehler nennen. Ich habe die Disassemblierung der '@ [obj]' - und der '[NSArray arrayWithObject: obj]' -Variante für x86_64 mit -Os-Optimierung unter LLVM 4.1 betrachtet; und der Compiler fügt vor 'NSArray' einen Aufruf' obj_release' in 'obj' ein. Wenn nicht jemand klüger ist, als ich hereinspiele, würde ich es einen Fehler nennen. – FluffulousChimp

Antwort

1

Getestet habe ich nur den folgenden Code beide Gebäude für OSX (x86 64) und iOS Simulator und ich den Fehler

void test(BOOL arg) { 
    id obj = nil; 

    if (arg) { 
     obj = [NSObject new]; 
    } 
    @[obj]; 
    NSLog(@"Hi there"); 
} 

int main(int argc, const char * argv[]) { 
    @autoreleasepool { 
     test(YES); 
    } 
    return 0; 
} 

Der obige Code einfach nicht wiedergeben kann, druckt Hi there in der Konsole und kehrt zurück.

Meine Konfiguration ist die gleiche von Ihnen: XCode 4.5.2 und Apple Clang Version 4.1 (Tags/Apple/Clang-421.11.66) (basierend auf LLVM 3.1svn) als Compiler.

EDIT

Ich versuchte auch von der Kommandozeile zu kompilieren (nach #include <Foundation/Foundation.h> zu Beginn des obigen Beispiels Zugabe) unter Verwendung von

clang -fobjc-arc -framework Foundation main.m 

Und das Ergebnis war wieder

2012-12-03 12:47:45.647 a.out[39421:707] Hi there 

EDIT 2 Wie In den Kommentaren wurde darauf hingewiesen, dass es möglich ist, den Fehler zu reproduzieren, der die Optimierungsstufe über -O0 erhöht. Zusammenfassend:

clang -O0 -fobjc-arc -framework Foundation main.m 

das Programm als

clang -O1 -fobjc-arc -framework Foundation main.m 

der präsentierten Fehler in der Frage erwartet funktioniert auftaucht. Dies gilt für jede Optimierungsstufe über -O0

Es ist definitiv ein Fehler im Compiler.

+0

Das ist komisch. Und Sie sind sicher, dass Sie mit ARC kompilieren? –

+1

Welche Optimierungsstufe? Ich ** kann ** das OP-Problem mit jeder Optimierungsebene über "-O" reproduzieren. Ohne Optimierungen scheint der Compiler "obj" nicht zu überlasten - sonst tut er es. – FluffulousChimp

+0

Ah Entschuldigung, jetzt sehe ich '-fobj-arc'. Yepp, dein Beispiel funktioniert auch für mich, aber wenn ich '-Os' als Standard-iOS-Release-Build-Konfiguration hinzufüge, scheint es zu viel zu veröffentlichen. –

1

Sie verpassen nichts. Es ist ein Compilerfehler.

Verwandte Themen