objective-cxcode

Xcode doesn't warn for invalid init methods


I just noticed that if you try to call a non-existing init method on the same line as an alloc statement, XCode will not warn you about this.

NSString *string = [[NSString alloc] initWithFrame:CGRectMake(0, 0, 0, 0)];
UIView *view = [[UIView alloc] initWithCapacity:0];

No warnings for either of those lines of code. Now, I guess this is because "alloc" actually returns id, as opposed to a static type. However, when I start to type "init," XCode gives me autocomplete options that only include init methods for the correct type. So, if is it using my static typing at the start of the line to give me autocomplete options, why isn't it also using that to give me a warning? Is this a setting somewhere in XCode that could be turned on?

Obviously it doesn't matter as much for obviously wrong things like those examples, but for some objects, this can cause runtime errors due to typos or forgetting to change one thing when you change another thing. I could also get a compiler warning by separating the alloc and init methods into 2 different lines of code, but I have never seen this done; I have always learned to use one line of code for alloc and init.


Solution

  • First of all, interesting question!

    XCode uses gcc output to create list of warnings and errors and some other (internal) mechanism to create list of autocomplete suggestions. Autocomplete is more clever sometimes (and sometimes not, you know :)

    But why doesn't gcc reports warning? You already have an answer -- alloc returns id.

    My answer is not an 'answer', but I want to share with you with the next. (Sorry, I don't have Mac at a moment, so it is not Apple's objective-c)

    shum@shum-laptop:/tmp/shum$ cat test.m 
    
    #import <objc/Object.h>
    
    @interface Test1 : Object
    {
    }
    
    - (id) blah;
    
    @end
    
    @interface Test : Object
    {
    }
    
    @end
    
    @implementation Test
    
    @end
    
    int main()
    {
      Test* test = [[Test alloc] blah];
      return 0;
    }
    
    shum@shum-laptop:/tmp/shum$ gcc test.m -lobjc
    shum@shum-laptop:/tmp/shum$ 
    

    No warning. But try to comment - (id) blah in Test1 interface

    shum@shum-laptop:/tmp/shum$ gcc test.m -lobjc
    test.m: In function ‘main’:
    test.m:24: warning: no ‘-blah’ method found
    test.m:24: warning: (Messages without a matching method signature
    test.m:24: warning: will be assumed to return ‘id’ and accept
    test.m:24: warning: ‘...’ as arguments.)
    shum@shum-laptop:/tmp/shum$ 
    

    Can make a conclusion: if you make a typo calling init and there are no selector with the same name, then gcc should warn you; in a bad case, when a selector with the same name exists somewhere, gcc will not warn you. I don't have Mac and XCode at a moment, could you please test it?

    [EDIT] Just tested it with the xcode. The same behavior.