Objective c 动态类型化类在方法选择时生成编译器警告

Objective c 动态类型化类在方法选择时生成编译器警告,objective-c,compiler-warnings,dynamic-typing,Objective C,Compiler Warnings,Dynamic Typing,也许这是一种错误的方法,但这似乎是一种干净可行的方法,我想知道如何才能消除编译器警告 @interface SomeView : UIView { NSString *stringOfsomeImportance; RelatedClass *niftyService; } @property (nonatomic, copy) NSString * stringOfnoImportance; @property (nonatomic, retain) RelatedClass *nifty

也许这是一种错误的方法,但这似乎是一种干净可行的方法,我想知道如何才能消除编译器警告

@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];
现在,看看RelatedClass实现

@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
这似乎是一个有效的方法,所以我想知道为什么会出现警告? 有没有办法更好地向编译器“解释”这一点

如果鼓励这种联系,或者有更好的方法将两个相互关联、相互依存、需要相互交流的类联系起来,有人能分享一下吗

我无法在RelatedClass中静态声明发送方对象(SomeView),因为这似乎会导致递归问题,因为SomeView是以RelatedClass作为成员定义的

有什么建议吗

  • 您可以定义一个协议,并说您的<代码>Sender对象必须符合该协议:

    @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
    }
    
  • 编辑:实际上,您还可以使用转发类声明将Sender定义为RelatedClass中的SomeView*:

    //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
    
  • 对于上面所描述的生成警告,完全是因为方法
    -otherMethods
    没有在编译器尝试编译调用站点之前看到声明的地方声明

    即方法的声明:

    - (void) otherMethods;
    
    必须出现在由编译特定调用站点的实现文件直接或间接导入的头文件中,或者方法声明必须出现在调用站点之前的
    @implementation
    中。

    在头文件中,可以转发声明要使用的类。在实现文件中,可以包含转发声明的类的完整头

    例如:


    SomeView.h
    相关类
    不过,这其实不是问题所在。协议确实解决了问题,但只有先解决真正的问题。
    id  thesender = ....;
    [thesender otherMethods];  // this generates a compiler warning
                               // that otherMethods cannot be found
                               // in SomeView, though it *is* found
                               // and seems to execute just fine
    
    - (void) otherMethods;
    
    #import <FrameworkHeader.h>
    
    // Here, you are saying that there is a class called RelatedClass, but it will be
    // defined later.
    @class RelatedClass;
    
    @interface SomeView : UIView
    {
        RelatedClass *niftyService;
    }
    
    @end
    
    #import "SomeView.h"
    #import "RelatedClass.h"
    
    // By including "RelatedClass.h" you have fulfilled the forward declaration.
    
    @implementation SomeView
    // Can use "RelatedClass" methods from within here without warnings.
    @end
    
    #import <FrameworkHeader.h>
    
    @class SomeView;
    
    @interface RelatedClass
    {
        SomeView *someView;
    }
    // methods
    @end
    
    #import "RelatedClass.h"
    #import "SomeView.h"
    
    @implementation RelatedClass
    // Can use "SomeView" methods from within here without warnings.
    @end