Is there a way to trap messages sent to nil in Objective-C?

前端 未结 2 1613
说谎
说谎 2021-02-20 06:12

I\'ve just been bitten by an annoying bug that was made obscure by the \"send message to nil is ok\" behaviour in Objective-C.

I\'ve seen Sending a message to nil?, and

相关标签:
2条回答
  • 2021-02-20 06:52

    You could use a ObjC undocumented trick or dtrace (see the comments for the dtrace solution).

    pid$1::objc_msgSend:entry
    /arg0==0/
    {
      ustack();
    }
    
    0 讨论(0)
  • 2021-02-20 07:13

    nil messaging is used very commonly in ObjC. Folks can fight over whether this is good or bad; it's just something you have to get used to. If you try to break it with tricks, then you're going to break Cocoa because Cocoa uses it. There are some tricks (like diciu posted) that will make it possible to debug in situations where you suspect nil messaging but just can't seem to find it. But you can't just leave those in your code (and the blog post above makes that clear). nil messaging is just too common inside the frameworks.

    To your original point, though, compare:

    - (void)doSomethingWith:(id)x {
        NSAssert(x != nil, @"Don't pass me nil");
        [x something];
    }
    

    vs.

    void Bar::DoSomething(Foo *x) {
        assert(x != NULL);
        if (x != NULL) {
           x.something;
        }
    }
    

    In both cases, you need to test, and in both cases the compiler won't warn you if you fail to test. The only difference is in what cases you crash/assert. Personally, I write macros around NSAssert() that make it always print a log message if it fails. It just only crashes in Debug. That way when a customer sends me logs, I can see what assertions failed.

    0 讨论(0)
提交回复
热议问题