Compiler error - method not found on object which conforms to protocol


Sandor Szatmari
 

I have a server class which is abstracted to receive it’s final configuration from it’s data source. The idea is you instantiate the server set the data source and then start the server. During startup the server reads some configuration, such as the port to start on, from the data source. This is outlined in pseudocode below. This is mostly working except for a compiler error I can’t explain. The compiler issues an error about accessing the port from the data source.

Port = self.dataSource.serverPort;

It says “Property ‘-serverPort’ not found on object of type ‘id<dataSrcProto>’”

Anyone come across this?

——— server.h/m ———-
@class server
@property (readwrite,assign) id<dataSrcProto> dataSource
-(void)start
{
Port = self.dataSource.serverPort;
… start the server
}
@end

——— dataSource.h/m ———-
@class dataSource <dataSrcProto>
-(NSUinteger)serverPort{return 8080;}
@end

——— dataSrcProto.h ———-
@protocol dataSrcProto
-(NSUinteger)serverPort;
@end

Sandor


Sak Wathanasin
 



On 27 Mar 2021, at 01:41, Sandor Szatmari <admin.szatmari.net@...> wrote:
@protocol dataSrcProto
-(NSUinteger)serverPort;
@end

serverPort isn't a property, so you have to use

[self.dataSource serverPort];

If you want it to be a property, make it so

@protocol dataSrcProto
@property (readonly) NSUinteger serverPort;
@end

Regards
Sak


Sandor Szatmari
 

Thanks Sak,

On Mar 27, 2021, at 04:54, Sak Wathanasin <sw@...> wrote:

On 27 Mar 2021, at 01:41, Sandor Szatmari <admin.szatmari.net@...> wrote:
@protocol dataSrcProto
-(NSUinteger)serverPort;
@end

serverPort isn't a property, so you have to use

This is how I’m working around the error right now.  Like this I get a compiler warning, method not found, return type defaults to id.  
[self.dataSource serverPort];


Port = (NSUInteger)[self.dataSource serverPort];

This succeeds at runtime, but of course smells, and doesn’t squelch the warning.

If you want it to be a property, make it so

I tried implementing serverPort as a property and I still get the same error

Thanks,
Sandor


@protocol dataSrcProto
@property (readonly) NSUinteger serverPort;
@end

Regards
Sak


Allan Odgaard <groups-io@...>
 

On 27 Mar 2021, at 2:41, Sandor Szatmari wrote:

[…] This is outlined in pseudocode below.

There is nothing conceptually wrong with what you sketch in your pseudo-code.

Please post an actual runnable example, as your pseudo-code has typos and lack context, something like the below compiles (and runs) just fine:

@protocol dataSrcProto
- (NSUInteger)serverPort;
@end

@interface MyDataSource : NSObject <dataSrcProto>
@end

@implementation MyDataSource
- (NSUInteger)serverPort { return 8000; }
@end

int main (int argc, char const* argv[])
{
    id <dataSrcProto> server; // obtained from seomewhere
    fprintf(stderr, "%ld\n", server.serverPort);
    return 0;
}


Sak Wathanasin
 



On 27 Mar 2021, at 13:54, Sandor Szatmari <admin.szatmari.net@...> wrote:

I tried implementing serverPort as a property and I still get the same error


As Allan suggested, maybe you should post the actual code. I have this same usage in my code and it builds & runs just fine.

Regards
Sak


Sandor Szatmari
 

Thanks for everyone’s help and I’m sorry I was unable to share the code.  I’m sure it would have been obvious and everyone would have see the issue with the actual code available.

It turns out that I only had a forward declaration of the protocol in the header, once I added an actual import of the protocol to the ‘.m’ file, the error was resolved.  

Thanks again for everyone’s thoughts!

Sandor

On Mar 27, 2021, at 12:39, Sak Wathanasin <sw@...> wrote:



On 27 Mar 2021, at 13:54, Sandor Szatmari <admin.szatmari.net@...> wrote:

I tried implementing serverPort as a property and I still get the same error


As Allan suggested, maybe you should post the actual code. I have this same usage in my code and it builds & runs just fine.

Regards
Sak


Alex Zavatone
 

Hi.  I’m late to the discussion, but have you put the property or method on the class?

When you have a class that conforms to a protocol, my understanding is that you cross your heart and swear to die that you will make sure that the class doing the conforming will implement those methods/properties.  

I’m not sure if this would work with inherited methods or properties as I’ve never tried it.

Now, if a method missing for a property (if it is implemented), I’d expect it would be accessor methods.  If your conforming class has the property declared, try creating the set and bet methods.  If the property isn’t declared, try declaring it and I’d expect Objectice-C to auto declare the accessors.  If it doesn’t, then add them to see if the error goes away.

Best of luck,
Alex Zavatone

On Mar 27, 2021, at 8:54 AM, Sandor Szatmari <admin.szatmari.net@...> wrote:

Thanks Sak,

On Mar 27, 2021, at 04:54, Sak Wathanasin <sw@...> wrote:

On 27 Mar 2021, at 01:41, Sandor Szatmari <admin.szatmari.net@...> wrote:
@protocol dataSrcProto
-(NSUinteger)serverPort;
@end

serverPort isn't a property, so you have to use

This is how I’m working around the error right now.  Like this I get a compiler warning, method not found, return type defaults to id.  
[self.dataSource serverPort];


Port = (NSUInteger)[self.dataSource serverPort];

This succeeds at runtime, but of course smells, and doesn’t squelch the warning.

If you want it to be a property, make it so

I tried implementing serverPort as a property and I still get the same error

Thanks,
Sandor


@protocol dataSrcProto
@property (readonly) NSUinteger serverPort;
@end

Regards
Sak


Sandor Szatmari
 

Alex,

Thanks for your input.

On Mar 30, 2021, at 10:13, Alex Zavatone via groups.io <zav@...> wrote:

Hi.  I’m late to the discussion, but have you put the property or method on the class?
Yes, the conforming class did have the method/property implemented.  

When you have a class that conforms to a protocol, my understanding is that you cross your heart and swear to die that you will make sure that the class doing the conforming will implement those methods/properties.  
Yes the compiler warns if the conforming class does not fully implement the protocol.  And of course there are required and optional aspects to a protocol. The compiler only warns about required elements that are missing.


I’m not sure if this would work with inherited methods or properties as I’ve never tried it.

Now, if a method missing for a property (if it is implemented), I’d expect it would be accessor methods.  If your conforming class has the property declared, try creating the set and bet methods.  If the property isn’t declared, try declaring it and I’d expect Objectice-C to auto declare the accessors.  If it doesn’t, then add them to see if the error goes away.

I had all the pieces in place except for the import to inform the compiler of the methods declared in the protocol.  The forward declaration in the header slightly masked the issue so that I didn’t recognize why the error was being generated. 

The object was already declared as conformant

@property (readonly) id<DataSrcProto> dataSource;

But, without the actual import in the scope of the compilation unit, the compiler had no idea what methods were actually declared in the protocol.

Thanks,
Sandor

Best of luck,
Alex Zavatone

On Mar 27, 2021, at 8:54 AM, Sandor Szatmari <admin.szatmari.net@...> wrote:

Thanks Sak,

On Mar 27, 2021, at 04:54, Sak Wathanasin <sw@...> wrote:

On 27 Mar 2021, at 01:41, Sandor Szatmari <admin.szatmari.net@...> wrote:
@protocol dataSrcProto
-(NSUinteger)serverPort;
@end

serverPort isn't a property, so you have to use

This is how I’m working around the error right now.  Like this I get a compiler warning, method not found, return type defaults to id.  
[self.dataSource serverPort];


Port = (NSUInteger)[self.dataSource serverPort];

This succeeds at runtime, but of course smells, and doesn’t squelch the warning.

If you want it to be a property, make it so

I tried implementing serverPort as a property and I still get the same error

Thanks,
Sandor


@protocol dataSrcProto
@property (readonly) NSUinteger serverPort;
@end

Regards
Sak