文章

空对象调用实例方法会崩溃吗

什么是空对象?

当你声明一个对象,并且没有赋值的时候, 对象的值是 nil,它是个标识符,表示对象指针没有指向任何实例。 当然还有 [NSNull null],是空对象。

小问题:发明[NSNull null]是什么用的呢?

在处理集合类(NSArray, NSDictionary 等)时,用空对象来表示一个空的占位,因为这些集合不能包含 nil。

如果奔溃是什么样子的?

报一个不认识的方法发送给了实例 unrecognized selector sent to instance

怎么分析会不会崩溃?

那就看 OC 方法调用的本质了,也就是 runtime 的消息发送方法 objc_msgSend。 直接找到源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
MSG_ENTRY _objc_msgSend
UNWIND _objc_msgSend, NoFrame

cmp p0, #0            // nil check and tagged pointer check
#if SUPPORT_TAGGED_POINTERS
b.le LNilOrTagged     //  (MSB tagged pointer looks negative)
#else
b.eq LReturnZero
#endif
ldr p14, [x0]         // p14 = raw isa
GetClassFromIsa_p16 p14, 1, x0  // p16 = class
LGetIsaDone:
    // calls imp or objc_msgSend_uncached
    CacheLookup NORMAL, _objc_msgSend, __objc_msgSend_uncached

#if SUPPORT_TAGGED_POINTERS
LNilOrTagged:
b.eq LReturnZero      // nil check
GetTaggedClass
b LGetIsaDone
// SUPPORT_TAGGED_POINTERS
#endif

方法里做了 nil check, 所以空对象调用它自己的实例方法不会崩溃啦~

本文由作者按照 CC BY 4.0 进行授权