method confusion

  • 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?

    Hans van der Meer
  • On 9/17/07, Hans van der Meer <hansm...> wrote:

    > Presumably it is some silly mistake. Can someone point me in the
    > right direction?

    In the file that is failing to compile make sure to #include the
    header for your class.

    The compiler doesn't see your method so it assumes you are attempting
    to use the only method with that signature.

    -Shawn
  • --- Hans van der Meer <hansm...> 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;
    > [SNIP]
    > I fail to see why this is possible, as these
    > declarations are in
    > different classes.

    But the compiler can't tell which class the method is
    being sent to. The alloc method has a return type of
    id, which could be anything. So when you send
    initWithSize: to the result of alloc, the compiler
    doesn't know what class it's talking to. I would
    change the method name to something that doesn't
    conflict, but if you have to keep it the same, you can
    statically type it as [(HMCharacterAlphabet
    *)[HMCharacterAlphabet alloc] initWithSize: 3]. This
    will give the compiler the information it needs to use
    the right method signature.

    Cheers,
    Chuck


    ____________________________________________________________________________________
    Pinpoint customers who are looking for what you sell.
    http://searchmarketing.yahoo.com/
  • 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

    ___________________________________________________________
    Ricky A. Sharp        mailto:<rsharp...>
    Instant Interactive(tm)  http://www.instantinteractive.com
  • On 9/17/07, Shawn Erickson <shawnce...> wrote:
    > On 9/17/07, Hans van der Meer <hansm...> wrote:
    >
    >> Presumably it is some silly mistake. Can someone point me in the
    >> right direction?
    >
    > In the file that is failing to compile make sure to #include the
    > header for your class.
    >
    > The compiler doesn't see your method so it assumes you are attempting
    > to use the only method with that signature.

    Sorry I missed the "multiple methods named" error...

    -Shawn
previous month september 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
Go to today