Objc headers - 函数和协议声明

Objc headers - Fonction & protocols declaration

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

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

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

我的 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 中,您通常将 class 放在自己的 .h 和 .m 文件中。 接口在.h中,实现在.m中。您可以将接口视为没有实现细节的可用消息列表,然后实现就是它的实际实现。

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

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

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

你可能有这样的事情

A.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,反之亦然。您可以通过告诉编译器您将拥有每种类型的 class 来解决此问题,如下所示。

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

编辑

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

@class MyViewController;

取而代之。