Search code examples
objective-ccompiler-warningsdynamic-typing

Dynamically typed class generates compiler warnings on method selection


Perhaps this is the wrong way to go about this, but it seems like such a clean and workable approach that I wonder how I can make the compiler warning go away?

@interface SomeView : UIView {
 NSString *stringOfsomeImportance;
 RelatedClass *niftyService;
}
@property (nonatomic, copy) NSString * stringOfnoImportance;
@property (nonatomic, retain) RelatedClass *niftyService;

@implementation
-(void)someMethod;
-(void)otherMethods;

@implementation    RelatedClass *pvSomeObj = [[RelatedClass alloc] initWithSender:self];
[self setNiftyService:pvSomeObj];

Now, looking at the RelatedClass implementations...

@interface RelatedClass : NSObject {
  id  thesender;

@property (nonatomic, retain) id thesender;


@implementation

[thesender otherMethods];  // this generates a compiler warning
                           // that otherMethods cannot be found
                           // in SomeView, though it *is* found
                           // and seems to execute just fine

This seems like a valid approach, so I'm left wondering why the warning? Is there a way to better "explain" this to the compiler?

Could someone kindly share if this type of linkage is encouraged or if there is a better way to link two related, interdependent classes that need to communicate with one another?

I can't statically declare the sender object (SomeView) in RelatedClass because that seems to cause a recursion problem, as SomeView is defined with RelatedClass as a member...

Any suggestions?


Solution

    1. You can define a protocol and say that your thesender object must conform to it:

      @protocol MyProtocol
         -(void)otherMethods;
      @end
      
      @interface RelatedClass : NSObject {
         id<MyProtocol>  thesender; // Now compiler knows that thesender must respond 
                                    // to otherMethods and won't generate warnings
      }
      
    2. You can send otherMethods message another way (you may need to define theSender as NSObject here):

      if ([theSender respondsToSelector:@selector(otherMethods)])
          [theSender performSelector:@selector(otherMethods)];
      
    3. Edit: Actually you can also define thesender as SomeView* in your RelatedClass using forward class declaration:

      //SomeView.h
      @class RelatedClass;
      @interface SomeView : UIView {
         RelatedClass *niftyService;
      }
      // then include RelatedClass.h in SomeView.m
      
      //RelatedView.h
      @class SomeView;
      @interface RelatedClass : NSObject {
         SomeView*  thesender;
      }
      // then include SomeView.h in RelatedClass.m