iOS

iOS调用不存在的方法

2020-03-22  本文已影响0人  码农二哥

问题

场景

我们知道,在oc中,当我们调用一个类中不存在的方法,会发生crash,错误信息大概是这样做:


image.png

预备

问题:

打断点摸索一下

首先:

// 调用一个不存在的方法
[self performSelector:@selector(aaa:)];

第二:

image.png

第三:

image.png

第四:

image.png

问题:

如果在类中对这两个方法这样重写,猜猜看forwardInvocation会被调用么?想想为什么?

- (void)forwardInvocation:(NSInvocation *)anInvocation {
    if ([anInvocation selector] == @selector(jump)) {
        Monkey *monkey = [[Monkey alloc] init];
        [anInvocation invokeWithTarget:monkey];
    }
    [super forwardInvocation:anInvocation];
}

- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector {
    if (aSelector == @selector(jump)) {
        return [NSMethodSignature signatureWithObjCTypes:"V@:@"];
    }
    return [super methodSignatureForSelector:aSelector];
}

第五:

image.png

forwardInvocation中的断点并没有走到,而是直接doesNotRecognizeSelector了。找个理由解释一下?

NSObject中doesNotRecognizeSelector的默认实现类似如下代码:

// Replaced by CF (throws an NSException)
+ (void)doesNotRecognizeSelector:(SEL)sel {
    _objc_fatal("+[%s %s]: unrecognized selector sent to instance %p", 
                class_getName(self), sel_getName(sel), self);
}

那么是不是可以理解为:我在子类重写doesNotRecognizeSelector方法,不调用[super ]就不会crash了呢?


image.png

实际测试一下,依然会crash,想想为什么呢?欢迎吐槽抛抛出来的问题。

官方文档

上一篇 下一篇

猜你喜欢

热点阅读