【问题标题】:Objc headers - Fonction & protocols declarationObjc 标头 - 函数和协议声明
【发布时间】:2020-09-03 17:33:44
【问题描述】:

我已经在 swift 上编程几年了,但我最近才尝试更好地理解 Objc。 我正在自己做一个小项目,使用 VIPER 架构。我有一个使用 VIPER 的示例 .swift 项目,现在我只想将其“翻译”为 objc 以了解语法。

我对 .h/.m 文件有一些问题: 我不知道我是否应该在 .m 或 .h 文件(分别)或在 .h 或 .m 文件(与它们所属的类)中声明我的协议。 我选择将它们全部放在一个 .h 文件中,并创建了一个 .m 文件来导入它。但这似乎真的很糟糕,因为 .m 是空的。 此外,在这些协议中调用“MyViewController”作为类型时,我会收到诸如“预期类型”之类的错误。

100% 确定问题来自标题。我知道“.h”必须从“.m”文件中导入才能编译,我也知道我们不应该多次调用标题。 但是,当我有 A.h/B.h 文件并且我需要来自 B 的 A 和来自 A 的 B 的东西时,感觉就像我卡住了。在这种情况下,我该如何摆脱困境?

我的 protocol.h 看起来像这样:

@protocol SampleProtocol
+ (MyViewController*) createModule; // Error: Expected a type
- (void) pushToView: (UINavigationController*)navController;
@end

MyViewController.h 看起来像这样:

@interface MyViewController : UIViewController
@property id<PresenterToRouterObjcProtocol> protocol;
@end

感谢您的帮助,希望您能启发我了解我所缺少的作品!

【问题讨论】:

    标签: objective-c header protocols


    【解决方案1】:

    在 Objective-C 中,您通常将一个类存放在其自己的 .h 和 .m 文件中。 接口在.h中,实现在.m中。您可以将接口视为没有实现细节的可用消息列表,然后实现就是它的实际实现。

    它可以追溯到 C 中,你有 .h 和 .c 文件。 .h 文件给出了函数的定义,以便使用它的其他代码知道如何调用它。

    Objective-C 协议只是一个没有实现的接口,实现该协议的类必须提供实际的实现。也就是说,协议将只有一个 .h 文件。协议通常会为要实现的类指定必需的和可选的消息。

    我希望这有助于理解,现在如何解决您的问题。这种情况并不经常发生,但有时确实会发生,您需要 B 中的 A,同时也需要 A 中的 B。在这里,我假设 A 和 B 是类,每个类都有自己的 .h 和 .m 文件。该问题将是头文件中的问题。

    你可能有这样的事情

    啊.h

    #import <Foundation...>
    #import "B.h"
    
    // Define class A
    @interface A : NSObject
    
    // Say this one has a property B
    @property (nonatomic,strong) B * b;
    
    @end
    

    B.h

    #import <Foundation...>
    #import "A.h"
    
    // Define class B
    @interface B : NSObject
    
    // Say this one has a property A
    @property (nonatomic,strong) A * a;
    
    @end
    

    现在你有一个先有鸡还是先有蛋的局面。你不能在不知道 B 的情况下定义 A,反之亦然。您可以通过告诉编译器您将拥有每种类型的类来解决这个问题,如下所示。

    A.h(B.h 会非常相似)

    #import <Foundation...>
    
    // No more import of B.h, but define it for compiler in general terms
    @class B; // Now compiler knows there will be a B
    
    // Define class A
    @interface A : NSObject
    
    // This will work now as the compiler knows B is coming later
    @property (nonatomic,strong) B * b;
    
    @end
    

    编辑

    一些细节......以上是一般的答案,更具体一点,你不应该在一个头文件中放置多个类或协议。每个都应该有自己的 .h 文件。并解决您的问题,删除导入并使用

    @class MyViewController;
    

    取而代之。

    【讨论】:

    • 这是金子,你已经回答了一切!我真的很高兴我问了,你先生让我很开心:)
    • 谢谢 - 我很感激......并且只是在我的回答中注意到一个错字!当然@interface@implementation 不带花括号,而是@end
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多