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.
+1 für die Buchung eines SSCCE –
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 –
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