//Section 1 (declarations)
NSString *foo;
NSString *bar;
NSDictionary *foobar =
@{
@"bar":^{return @"foo";}
};
typedef NSString *(^barfoo)();
Warum erzeugt nur die letzte Zeile des folgenden Objective-C-Codes die obigen Deklarationen
EXC_BAD_ACCESS-Code = 1
//Section 2 (crashes)
foo = foobar[@"bar"]; //no error, foo == @"foo"
bar = foobar[@"foo"]; //no error, bar == nil
foo = ((barfoo)foobar[@"bar"])(); //no error, foo == @"foo"
bar = ((barfoo)foobar[@"foo"])(); //EXC_BAD_ACCESS code=1
NSLog(@"%@%@",foo,bar); // never runs!
Ich sollte beachten, dass der Fang beim Versuch / Fangen nichts fängt; es wird keine Ausnahme ausgelöst. Ändern foobar
"s Inhalt zu @{@"bar":^NSString*{return @"foo";}
hilft nicht.
Ich sollte auch den folgenden Code beachten funktioniert und macht keinen Fehler:
//Alternate Section 2 (does not crash)
barfoo foobard = foobar[@"foo"];
barfoo barfood = foobar[@"bar"];
barfood ? foo = barfood() : nil;
foobard ? bar = foobard() : nil;
NSLog(@"%@%@",foo,bar); // Returns foo(null)
Hinweis: Der Code wird unter iOS 9.2.1 ausgeführt.
Antworten:
4 für die Antwort № 1Ich bin verwirrt, warum Sie sind verwirrt
Schon seit foobar[@"foo"]
ist nil
(wie Ihre Kommentare richtig zeigen) können Sie es nicht als Block behandeln und nicht aufrufen. Deswegen ((barfoo)foobar["@foo"])()
stürzt ab.
Das zweite Codesegment ruft einfach nichts auf, wenn es das Objekt erkennt, das Sie aus dem Wörterbuch erhalten haben nil
daher tut es nichts mit der Rückkehr von foobar[@"foo"]
Bezüglich der try catch
- Es wird kein Fehler ausgegeben stürzt ab. Das ist etwas anderes. Etwas, von dem sich das Programm nicht erholen kann. Etwas, das Sie als Entwickler sicherstellen müssen, geschieht nicht. Es ist Ihre Aufgabe sicherzustellen, dass der Block, den Sie aufzurufen versuchen, tatsächlich nichtnil
.