0

I've been scratching my head about this for the last 4 hours, trying out all kinds of little experiments, but I can't seem to figure out what's going wrong. Could this be a compiler bug?

Test.m:

- (id)initWithContentsOfURL:(NSURL *)aURL error:(NSError **)error
{
    if (!(self = [super init])) {
        return nil;
    }
    return self;
}

main.m:

NSError *error;

Test *t = [[Test alloc] initWithContentsOfURL:[NSURL fileURLWithPath:@"/"] error:&error];

Here's the compiler warning (from main.m):

warning: incompatible Objective-C types 'struct NSError **', expected 'struct NSDictionary **' when passing argument 2 of 'initWithContentsOfURL:error:' from distinct Objective-C type

I'm using the latest versions of Xcode and Snow Leopard.

splicer
  • 5,344
  • 4
  • 42
  • 47

1 Answers1

5

I suspect that it's picking up a different instance of the selector, initWithContentsOfURL:error: - perhaps the one in NSAppleScript. Remember that [NSObject alloc] returns an id.

Does your code work as expected at runtime?

Try casting the return of [Test alloc] to Test*.

i.e.


Test *t = [(Test*)[Test alloc] initWithContentsOfURL:[NSURL fileURLWithPath:@"/"] error:&error];
philsquared
  • 22,403
  • 12
  • 69
  • 98
  • 3
    You're correct. Objective-C doesn't like methods with the same signature to have different types (i.e. it doesn't do overloading), so avoid naming two methods the same if they take different parameters. –  Apr 07 '10 at 11:09
  • That was it! Thanks! I had no idea Objective-C could run into these namespace pollution problems. You'd think Apple would have addressed this in Objective-C 2.0... – splicer Apr 07 '10 at 11:18
  • 1
    Yeah, it's a nasty one. I was bitten by it a while back: http://stackoverflow.com/questions/312608/why-do-i-need-to-cast-self-to-id – philsquared Apr 07 '10 at 11:20
  • Saying ObjC doesn't like methods with the same signature to have different types is like saying C doesn't like passing a `struct *` pointer to a function that takes a `void *` type. ObjC is just fine with methods with the same signature and different types (ie, different classes using the same selector but different types for the parameters). It does have a problem when you use `id` as the object type in such cases because it is ambiguous as to "which one you mean"- `id` means it can mean both. You need to statically type the object- `[(NSRightType *)[NSRightType alloc] init…]` – johne Apr 07 '10 at 15:05
  • I think Graham was probably thinking about trying to overload a method on the same class (which is not the case here). – philsquared Apr 07 '10 at 15:08