Chcę użyć przekazywania wiadomości, aby dowolna niezaimplementowana metoda pobierająca zwróciła 0, zamiast wyrzucać nierozpoznany wyjątek selektora. JakRóżne zachowanie emulatora iPhone'a i urządzenia rzeczywistego dotyczące przekazywania wiadomości
MyClass *r = [[MyClass alloc] init];
NSNumber *n = (NSNumber *)r;
NSLog(@"%d", [n integerValue]); // output 0
NSLog(@"%f", [n doubleValue]); // output 0.00000
NSLog(@"%@", [n stringValue]); // output (null)
Więc napisałem ten przykład:
#pragma mark -
#pragma mark Application lifecycle
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
NSNumber *n = (NSNumber *)self;
NSLog(@"%d", [n integerValue]);
NSLog(@"%f", [n doubleValue]);
NSLog(@"%@", [n stringValue]);
return YES;
}
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector {
NSMethodSignature *ms = [super methodSignatureForSelector:aSelector];
if(ms)
return ms;
// Q = uint64_t, so it should also works for double which is also 64bit
return [NSMethodSignature signatureWithObjCTypes:"[email protected]:"];
}
- (void)forwardInvocation:(NSInvocation *)anInvocation {
uint64_t ZERO64 = 0;
[anInvocation setReturnValue:&ZERO64];
}
Wynik wyjście na prawdziwym urządzeniu wynosi 0, 0,00000 (null), ale na emulatorze, to 0, NaN (null)
Tak więc podwójny typ nie działa zgodnie z oczekiwaniami. Moją pierwszą myślą jest zmiana NSMethodSignature na "d @:" (d jest podwójne)
Wynik wyjściowy jest prawidłowy dla obu urządzeń i symulatorów, ale na symulatorze dzieje się coś dziwnego. Uruchom ten kod i będzie rozbić na 6 pętli z jakimś wyjątkiem CALayer:
#pragma mark -
#pragma mark Application lifecycle
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
for(NSInteger i = 0; i < 100; i++) {
NSInteger t = [(NSNumber *)self integerValue];
UIViewController *view = [[UIViewController alloc] init];
// it always crash on the 6th loop on this line**
UINavigationController *nc = [[UINavigationController alloc] initWithRootViewController:view];
}
return YES;
}
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector {
NSMethodSignature *ms = [super methodSignatureForSelector:aSelector];
if(ms)
return ms;
// we change to return double
return [NSMethodSignature signatureWithObjCTypes:"[email protected]:"];
}
- (void)forwardInvocation:(NSInvocation *)anInvocation {
uint64_t ZERO64 = 0;
[anInvocation setReturnValue:&ZERO64];
}
Ciekawi mnie dwa pytania, dlaczego zwracany jest NAN na emulatorze w pierwszym przykładzie, a co się stało na sekundę przykład?
Ściśle związane: [Dlaczego wysyłanie dowolnego selektora do obiektu zerowego nic nie robi, ale wysłanie "Nieprawidłowy" selektor do dowolnego NSObject podnosi wyjątek?] (Http://stackoverflow.com/questions/11530133/why-is-it-that-sending-any-selector-to-a-nil-object-does-nothing -but-sending-an/11531609 # 11531609) i zobacz moją odpowiedź na implementację. –