2

也许这是解决此问题的错误方法,但它似乎是一种干净且可行的方法,我想知道如何使编译器警告消失?

@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 作为成员定义的......

有什么建议么?

4

3 回答 3

1
  1. 您可以定义一个协议并说您的thesender对象必须符合它:

    @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. 您可以通过otherMethods其他方式发送消息(您可能需要在theSender此处定义为 NSObject):

    if ([theSender respondsToSelector:@selector(otherMethods)])
        [theSender performSelector:@selector(otherMethods)];
    
  3. 编辑:实际上,您还可以使用前向类声明在您的相关类中将发送者定义为 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
    
于 2010-02-16T07:21:14.980 回答
1

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

例如:


一些视图.h

#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

SomeView.m

#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

相关类.h

#import <FrameworkHeader.h>

@class SomeView;

@interface RelatedClass
{
    SomeView *someView;
}
// methods
@end

相关类.m

#import "RelatedClass.h"
#import "SomeView.h"

@implementation RelatedClass
// Can use "SomeView" methods from within here without warnings.
@end
于 2010-02-16T08:14:24.887 回答
0
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

如您所描述的,上述生成警告完全是因为-otherMethods在尝试编译调用站点之前编译器在看到声明的某个地方没有声明该方法。

也就是方法的声明:

- (void) otherMethods;

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

于 2010-02-16T08:05:51.933 回答