views:

31

answers:

2

Hi

This is not an actual Xcode error message, it is a warning that has been haunting me for a long time. I have found no way of removing it and I think I maybe have overstepped some unwritten naming convention rule.

If I build a class, most often extending NSObject, whose only purpose is to do some task and report back when it has data, I often give it a convenience constructor like "initWithDelegate".

The first time I did this in my current project was for a class called ISWebservice which has a protocol like this:

@protocol ISWebserviceDelegate

@optional

- (void) serviceFailed:(NSError*) error;
- (void) serviceSuccess:(NSArray*) data;

@required

@end

Declared in my ISWebservice.h interface, right below my import statements.

I have other classes that uses a convenience constructor named "initWithDelegate". E.g. "InternetConnectionLost.h", this class does not however have its methods as optional, there are no @optional @required tags in the declaration, i.e. they are all required.

Now my warning pops up every time I instantiate one of these Classes with convenience constructors written later than the ISWebservice, so when utilizing the "InternetConnectionLost" class, even though the entire Class owning the "InternetConnectionLost" object has nothing to do with the "ISWebservice" Class, no imports, methods being called, no nothing, the warning goes: 'ClassOwningInternetConnectionLost' does not implement the 'ISWebserviceDelegate' protocol

I does not break anything, crash at runtime or do me any harm, but it has begun to bug me as I near release. Also, because several classes use the "initWithDelegate" constructor naming, I have 18 of these warnings in my build results and I am getting uncertain if I did something wrong, being fairly new at this language.

Hope someone can shed a little light on this warning, thank you:)

A: 

Your getting the warning because the compiler thinks that the classes have declared that they implement the ISWebserviceDelegate protocol. I doubt it has anything to do with the intiWithDelegate method unless your inheriting the method or you've defined the method in a protocol that itself is an extension of ISWebserviceDelegate protocol.

The usual cause of this is declaring the adoption of the protocol in a superclass and then forgetting to implement in that superclass of a subsequent subclass.

If you're sure that is not the case, then you probably just need to clean the project and rebuild. You most likely did declare at one point, then undeclared but the compiler is stuck on the old declaration.

If the clean does not resolve, I would do a project find on ISWebserviceDelegate and make sure its not tucked away somewhere.

TechZen
Hi TechZen.Thanks for your suggestions, they are all good, I went through them but still no luck.The warning has been around for more than a month of development so many "Clean all targets" have been done over that period.I made sure there where no classes with the warning that implemented the ISWebserviceDelegate and all of them either extends NSObject, UIViewController or UIView.
RickiG
Well, the only thing left is a category, probably on NSObject. Could be in a custom build script or something. I take it only does it on this one project? If not, then you might have a corrupt Xcode preference somewhere
TechZen
You might have someone else look over your code. A fresh set of eyes often sees things we don't when we've been staring at it every day.
TechZen
I have been through all the Categories in the project, no luck. When You wrote it I was sure that would be where the reference was hiding.I will have to spend some hours on this one I guess, making sure I investigated your suggestions all the way through the hierarchy.I am pretty sure you answered the question, but I just haven't found the exact line where it applies yet:)Thanks again for the "fresh eyes".
RickiG
A: 

The cause here is that you have multiple interfaces in your project that have functions defined as initWithDelegate:(id).

Alloc only returns id, so the compiler doesn't know the type, it therefore doesn't know which initWithDelegate is being used and seemingly uses the first one in the list. Thus you get a warning that makes no sense.

The runtime knows the type of the object however, and thus doesn't have any trouble.

The solution seemingly is to use more verbose init methods, eg. initWithWebServiceDelegate. Or to cast after the alloc:

[(Foo *)[Foo alloc] initWithDelegate:self]
Max Howell