ObjectProperties.h

@protocol ObjectProperties <NSObject>

@property (strong, nonatomic) NSString *name;
@property (strong, nonatomic) NSDate *date;
@property (assign, nonatomic) int64_t index;

@end

ClassA.h

#import <Foundation/Foundation.h>

@protocol ObjectProperties;

@interface ClassA : NSObject <ObjectProperties>

- (void)specialSauce;

@end;

ManagedClassA.h

#import <CoreData/CoreData.h>

@protocol ObjectProperties;

@interface ManagedClassA : NSManagedObject <ObjectProperties>

- (void)doSomething;

@end;

根据上面的代码示例,我在一个应用程序中定义了一个协议.与核心数据对象以及普通对象一起使用的h文件.有一致性的课程似乎是"噪音"‪#进口‬ 在他们的头文件中的协议;转发声明协议会更干净;进口‬ 在我上面展示的实现文件中.但是,Xcode在这样做时会抛出一个警告:

Cannot find protocol definition for 'ObjectProperties'

这段代码可以编译,而且大部分是有效的.我之所以这么说,主要是因为核心数据试图为标量属性动态创建getter/setter,这很有趣,但我认为这可能是因为我遇到了一个边缘情况.

当然,最明显的解决方法是将协议头导入到类头中.

如果我的理解是正确的(而且我的知识是最近获得的,所以我完全可能是错的),如果我将协议导入到我的类头中并对协议进行更改,那么所有导入我的类的后续文件都必须重新编译.

解决这类问题的正确方法是什么?

推荐答案

不能向前声明它所符合的超类或协议.在这些情况下,必须包含标题.这是因为(在超类的情况下)超类的实例变量和方法成为类的一部分;或者(在协议的情况下),协议的方法成为在类中声明的方法,而无需显式声明它们.(也就是说,现在包括你的类标题的其他人会看到你的类声明了这些方法,就像你自己声明了它们一样.)唯一可能的方法是,如果它们已经在此范围内定义,即导入它们的头.

#import <SomeClass.h>
#import <SomeProtocol.h> // these two must be imported

@interface MyClass : SomeClass <SomeProtocol>
@end

正向声明对于仅以变量类型(特别是对象指针变量)显示的内容非常有用.对象指针的大小都相同,在运行时不同类型的对象指针之间没有区别(对象指针类型的概念只是编译时的事情).所以没有必要确切地知道这些类型的类中有什么.因此,它们可以被提前声明.

@class SomeClass;
@protocol SomeProtocol; // you can forward-declare these

@interface MyClass {
    SomeClass *var1;
    id<SomeProtocol> var2;
}
@end

Objective-c相关问答推荐

使用 NSMutableString 附加到文件的末尾

核心数据 - 如何获取具有最大值属性的实体

如何从 Appdelegate 显示 UIAlertController

indexOfObject 对比indexOfObjectIdenticalTo

Objective C 代码是否有 github markdown 语言标识符?

烦人的[Environment: Sandbox]提示

在 iOS 设备上本地存储图像

如何在使用 React Native 时实现 SSL 证书固定

Objective-C 的 Eclipse 插件?

失go 对 UITextView 的关注时隐藏键盘

判断 NSInteger 是奇数还是偶数

如何隐藏/显示导航栏中的右键

从 UIPageViewController 中移除视图控制器

如何在 iOS 上将图像旋转 90 度?

委托如何在 Objective-C 中工作?

Objective-C 中的 super 到底是什么?

我应该使用 NSUserDefaults 还是 plist 来存储数据?

带有块的 Objective-C 延迟动作

获取当前调度队列?

如何判断数组是空还是空?