multiple methods named 'xxx' found.

  • Hi all,

    I found the below thread messages on the Cocoabuilder site.  Please
    have a quick look.  I understand what YMMV is saying, but does anyone
    know the reason why that warning occurs?  Wouldn't the fact that the
    two methods are defined in different classes enough to allow multiple
    methods with the same name and different arguments to exist?  I am
    getting the same problem in my project but I quickly fixed it by
    renaming my method.  I thought that was really odd.

    Nelson

    FROM : Ricky Sharp
    DATE : Mon Sep 17 23:50:08 2007

    On Sep 17, 2007, at 4:22 PM, Hans van der Meer wrote:

    > In my code I have in a testcase:
    > @interface HMCharacterAlphabetTest : SenTestCase {
    > ...
    > Inside one of the tests:
    > HMCharacterAlphabet *alphabet = [[HMCharacterAlphabet alloc]
    > initWithSize: 3];
    > defined in class HMCharacterAlphabet as:
    > - (id) initWithSize: (unsigned) size; // class in
    > HMCharacterAlphabet.h
    >
    > Somehow arises confusion with the identically typed init in
    NSImage.h:
    > - (id)initWithSize:(NSSize)aSize;
    >
    > Compiling gives:
    > warning: multiple methods named -initWithSize
    > error: incompatible type for argument 1 of initWithSize
    > warning: using -(id)initWithSize:(NSSize)aSize (NSImage.h:65)
    >
    > I fail to see why this is possible, as these declarations are in
    > different classes.
    > Presumably it is some silly mistake. Can someone point me in the
    > right direction?

    I believe the issue here is that both initWithSize: methods are
    ultimately being sent to id.

    I ran into a similar situation where one my custom control classes
    had this:

    - (int)currentValue
    {
        return [[self cell] currentValue];
    }

    When 10.4 was introduced, NSAnimation added a -(float)currentValue
    API.  The scary thing was that the code compiled.  At runtime, the
    control actually sent NSAnimation's message instead!  This is because
    [self cell] returns an id.  It then decided to send the animation's
    message (probably since it was picked up first due to importing
    <Cocoa/Cocoa.h> in my precomp header).

    In your case, it looks like you do have -Wstrict-selector-match in
    your 'Other C Flags' options.  That's a good thing (and other
    developers should consider turning that one on to catch these
    situations).

    There are then two workarounds:

    (A) explicit cast.  Not always good.  In my control's API, the
    workaround would look like this:

    return [(IIValueFieldCell*) [self cell] currentValue];

    But, I decided to do (B) instead:

    (B) Due to lack of namespacing, I made three key changes so that no
    collisions would ever occur:

    (1) All class names, constants, globals, structs, typedefs prefixed
    with II.  Most folks are doing this; picking a unique 2-letter prefix.

    (2) Suffix all ivars with _II (which then gave me unique accessors).
    For example:

    BOOL checked_II;
    -(BOOL)checked_II;
    -(void)setChecked_II:(BOOL)flag;

    I did the same thing for any custom bindings.

    (3) Suffix all methods (before first arg) with _II:

    - (int)computeSum_II
    - (void)initWithStudent_II:(IIStudent*)aStudent
    - (void)initWithStudentName_II:(NSString*)aName settings:(IISettings*)
    someSettings;

    messages are thus computeSum_II, initWithStudent_II: and
    initWithStudentName_II:settings:

    YMMV
  • --- Nelson Santos <nelsonsantos...> wrote:

    > Hi all,
    >
    > I found the below thread messages on the
    > Cocoabuilder site.  Please
    > have a quick look.  I understand what YMMV is
    > saying, but does anyone
    > know the reason why that warning occurs?  Wouldn't
    > the fact that the
    > two methods are defined in different classes enough
    > to allow multiple
    > methods with the same name and different arguments
    > to exist?

    I think it was explained pretty clearly in that
    thread. Yes, the two methods can both exist, but the
    compiler does not necessarily know which one you meant
    to call at a given point.

    Cheers,
    Chuck


    ____________________________________________________________________________________
    Need a vacation? Get great deals
    to amazing places on Yahoo! Travel.
    http://travel.yahoo.com/
  • Hi Charles,

    Thanks for the reply.  Well, that's the part I don't get.  Isn't the
    compiler smart enough to choose the appropriate method based on which
    object I am sending the message to?  If I am calling a method that is
    defined in the class of the object I am sending the message to, why
    would the compiler even think that I intend to call a completely
    unrelated class's method on my object?  How is that even possible if
    that is actually what I intended to do?

    Nelson

    On Oct 5, 2007, at 2:23 AM, Charles Steinman wrote:

    > --- Nelson Santos <nelsonsantos...> wrote:
    >
    >> Hi all,
    >>
    >> I found the below thread messages on the
    >> Cocoabuilder site.  Please
    >> have a quick look.  I understand what YMMV is
    >> saying, but does anyone
    >> know the reason why that warning occurs?  Wouldn't
    >> the fact that the
    >> two methods are defined in different classes enough
    >> to allow multiple
    >> methods with the same name and different arguments
    >> to exist?
    >
    > I think it was explained pretty clearly in that
    > thread. Yes, the two methods can both exist, but the
    > compiler does not necessarily know which one you meant
    > to call at a given point.
    >
    > Cheers,
    > Chuck
    >
    >
    >
    > ______________________________________________________________________
    > ______________
    > Need a vacation? Get great deals
    > to amazing places on Yahoo! Travel.
    > http://travel.yahoo.com/
  • Well, now that I think about this some more, in Cocoa it is possible
    to send any message to any class object, isn't that right?  Even if
    the method isn't defined in that class (or anywhere).  I suppose
    that's where the compiler's confusion comes in.  Am I on the ball, here?

    Nelson

    On Oct 5, 2007, at 8:18 AM, Nelson Santos wrote:

    > Hi Charles,
    >
    > Thanks for the reply.  Well, that's the part I don't get.  Isn't
    > the compiler smart enough to choose the appropriate method based on
    > which object I am sending the message to?  If I am calling a method
    > that is defined in the class of the object I am sending the message
    > to, why would the compiler even think that I intend to call a
    > completely unrelated class's method on my object?  How is that even
    > possible if that is actually what I intended to do?
    >
    > Nelson
    >
    >
    >
    > On Oct 5, 2007, at 2:23 AM, Charles Steinman wrote:
    >
    >> --- Nelson Santos <nelsonsantos...> wrote:
    >>
    >>> Hi all,
    >>>
    >>> I found the below thread messages on the
    >>> Cocoabuilder site.  Please
    >>> have a quick look.  I understand what YMMV is
    >>> saying, but does anyone
    >>> know the reason why that warning occurs?  Wouldn't
    >>> the fact that the
    >>> two methods are defined in different classes enough
    >>> to allow multiple
    >>> methods with the same name and different arguments
    >>> to exist?
    >>
    >> I think it was explained pretty clearly in that
    >> thread. Yes, the two methods can both exist, but the
    >> compiler does not necessarily know which one you meant
    >> to call at a given point.
    >>
    >> Cheers,
    >> Chuck
    >>
    >>
    >>
    >> _____________________________________________________________________
    >> _______________
    >> Need a vacation? Get great deals
    >> to amazing places on Yahoo! Travel.
    >> http://travel.yahoo.com/

  • On Fri, October 5, 2007 8:18 am, Nelson Santos said:
    > Hi Charles,
    >
    > Thanks for the reply.  Well, that's the part I don't get.  Isn't the
    > compiler smart enough to choose the appropriate method based on which
    > object I am sending the message to?  If I am calling a method that is
    > defined in the class of the object I am sending the message to, why would
    > the compiler even think that I intend to call a completely unrelated
    > class's method on my object?  How is that even possible if that is
    > actually what I intended to do?

    Actually it is smart enough, the problem is that you the call doesn't
    specify the object type that you are sending the message to.  If you _did_
    specify, then it wouldn't be a problem, but in this case it is very hard
    to specify.

    Let's take a look at that snippet of code again:
    [[HMCharacterAlphabet alloc] initWithSize: 3]

    You see it as 'Tell the HMCharacterAlphabet class to alloc a new instance,
    and init it with size 3'.  That's not quite what the compiler sees.  It
    sees 'Tell HMCharacterAlphabet to alloc a new instance, and tell the
    result of that to init itself with size 3.'

    Now, what is the result of [HMCharacterAlphabet alloc]?  Well, I'm
    guessing you didn't write that method for that class... (Please _don't_,
    by the way.)  So, who does it inherit it from?

    Go back up the inheritance tree, and you'll find that alloc is defined as
    a method of NSObject.  (Where else?)  And what does it return?  _id_  An
    unknown object.

    So the above snippet tells the compiler to send 'initWithSize:' to an
    unknown object.  Therefore the compiler needs to check _every possible
    class_ to figure out which ones respond to that.  Hopefully only one does,
    and then it can say 'Oh, I guess you mean send it there.'

    But if it finds two classes that can both respond to that method, it has
    to give an error, saying 'What do you want me to do?'

    There are obviously workarounds, once you know what is going on.  After
    all, all you need to do is define that 'id' as a member of some class for
    the compiler to know what you want to do.  And if you _really_ need to,
    you can use them.  Expect the next programmer who takes a look at your
    code (and you'll count as 'the next programmer' in a month) to look at the
    workaround to say 'That's ugly and useless', and remove it.  (And break
    the code therefore.)

    Better to try to find a unique name for that method.  Then people won't
    look at it funny.

    Daniel T. Staal

    ---------------------------------------------------------------
    This email copyright the author.  Unless otherwise noted, you
    are expressly allowed to retransmit, quote, or otherwise use
    the contents for non-commercial purposes.  This copyright will
    expire 5 years after the author's death, or in 30 years,
    whichever is longer, unless such a period is in excess of
    local copyright law.
    ---------------------------------------------------------------
  • Ahh... you are right! The message is sent to id, isn't it.  Of
    course!  It is obvious to me now.  The same thing was happening in my
    code as well.  Ok, so I was right in that if the message was actually
    being sent to the object class that defines the method, it would be
    OK.  But in this case, since the object is id, the compiler won't
    know which to use.  Perfectly clear now.  Thank you!

    Nelson

    On Oct 5, 2007, at 9:37 AM, Daniel T. Staal wrote:

    > On Fri, October 5, 2007 8:18 am, Nelson Santos said:
    >> Hi Charles,
    >>
    >> Thanks for the reply.  Well, that's the part I don't get.  Isn't the
    >> compiler smart enough to choose the appropriate method based on which
    >> object I am sending the message to?  If I am calling a method that is
    >> defined in the class of the object I am sending the message to,
    >> why would
    >> the compiler even think that I intend to call a completely unrelated
    >> class's method on my object?  How is that even possible if that is
    >> actually what I intended to do?
    >
    > Actually it is smart enough, the problem is that you the call doesn't
    > specify the object type that you are sending the message to.  If
    > you _did_
    > specify, then it wouldn't be a problem, but in this case it is very
    > hard
    > to specify.
    >
    > Let's take a look at that snippet of code again:
    > [[HMCharacterAlphabet alloc] initWithSize: 3]
    >
    > You see it as 'Tell the HMCharacterAlphabet class to alloc a new
    > instance,
    > and init it with size 3'.  That's not quite what the compiler
    > sees.  It
    > sees 'Tell HMCharacterAlphabet to alloc a new instance, and tell the
    > result of that to init itself with size 3.'
    >
    > Now, what is the result of [HMCharacterAlphabet alloc]?  Well, I'm
    > guessing you didn't write that method for that class... (Please
    > _don't_,
    > by the way.)  So, who does it inherit it from?
    >
    > Go back up the inheritance tree, and you'll find that alloc is
    > defined as
    > a method of NSObject.  (Where else?)  And what does it return?
    > _id_  An
    > unknown object.
    >
    > So the above snippet tells the compiler to send 'initWithSize:' to an
    > unknown object.  Therefore the compiler needs to check _every possible
    > class_ to figure out which ones respond to that.  Hopefully only
    > one does,
    > and then it can say 'Oh, I guess you mean send it there.'
    >
    > But if it finds two classes that can both respond to that method,
    > it has
    > to give an error, saying 'What do you want me to do?'
    >
    > There are obviously workarounds, once you know what is going on.
    > After
    > all, all you need to do is define that 'id' as a member of some
    > class for
    > the compiler to know what you want to do.  And if you _really_ need
    > to,
    > you can use them.  Expect the next programmer who takes a look at your
    > code (and you'll count as 'the next programmer' in a month) to look
    > at the
    > workaround to say 'That's ugly and useless', and remove it.  (And
    > break
    > the code therefore.)
    >
    > Better to try to find a unique name for that method.  Then people
    > won't
    > look at it funny.
    >
    > Daniel T. Staal
    >
    > ---------------------------------------------------------------
    > This email copyright the author.  Unless otherwise noted, you
    > are expressly allowed to retransmit, quote, or otherwise use
    > the contents for non-commercial purposes.  This copyright will
    > expire 5 years after the author's death, or in 30 years,
    > whichever is longer, unless such a period is in excess of
    > local copyright law.
    > ---------------------------------------------------------------
previous month october 2007 next month
MTWTFSS
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31        
Go to today