Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c 目标-C协议转发声明_Objective C_Protocols - Fatal编程技术网

Objective c 目标-C协议转发声明

Objective c 目标-C协议转发声明,objective-c,protocols,Objective C,Protocols,ObjectProperties.h @协议对象属性 @属性(强,非原子)NSString*名称; @属性(强,非原子)NSDate*日期; @属性(赋值,非原子)int64_t索引; @结束 A.h级 #导入 @协议对象属性; @接口ClassA:NSObject -(无效)特别拍卖; @结束; ManagedClassA.h #导入 @协议对象属性; @接口ManagedClassA:NSManagedObject -(无效)剂量测定; @结束; 从上面的代码示例中,我在.h文件中定义

ObjectProperties.h

@协议对象属性
@属性(强,非原子)NSString*名称;
@属性(强,非原子)NSDate*日期;
@属性(赋值,非原子)int64_t索引;
@结束
A.h级

#导入
@协议对象属性;
@接口ClassA:NSObject
-(无效)特别拍卖;
@结束;
ManagedClassA.h

#导入
@协议对象属性;
@接口ManagedClassA:NSManagedObject
-(无效)剂量测定;
@结束;
从上面的代码示例中,我在.h文件中定义了一个协议,用于核心数据对象和普通对象。有一致的类似乎是“噪音”‪#进口‬ 在他们的头中的协议;转发声明协议和导入会更干净‬ 在实现文件中,如上所示。但是,以这种方式执行时,Xcode会抛出警告:

找不到“ObjectProperties”的协议定义

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

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

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


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

是的,所有文件都需要重新编译,但这是必要的。导入类头的文件需要知道与其实现的协议关联的方法。如果将该定义隐藏在.m文件中,那么它只对一个文件可见(因为.m文件永远不会被导入)。它与前向声明类不同。如果转发声明协议,则必须在与转发声明在同一范围内可见的某个位置进行声明。我想不出在同一个文件中不发生这种情况的任何例子


在ARC中,这是一个错误,因为ARC需要了解所声明方法的内存管理(它们是否返回+1实例、内部指针等?

通过在MyClass.h中声明类,您必须导入其超类的所有头文件以及在MyClass.h文件中采用的协议。Objective-c中的协议被认为是一种变异的继承类型


转发声明通常在类的成员声明中使用。

因为您要声明与协议的一致性,所以应该导入包含协议的头

这与#导入超类相同,而不是向前声明它:

@class Foo;

@interface Bar : Foo
// Will get error: attempting to use the forward class 'Foo' as superclass of 'Bar'
@end;

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

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

@interface MyClass : SomeClass <SomeProtocol>
@end
#导入
#导入//必须导入这两个
@接口MyClass:SomeClass
@结束
正向声明对于仅在变量类型(特别是对象指针变量)中显示的内容非常有用。对象指针的大小都相同,并且在运行时不同类型的对象指针之间没有区别(对象指针类型的概念只是编译时的事情)。因此,没有必要确切地知道这些类型的类中有什么。因此,它们可以向前声明

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

@interface MyClass {
    SomeClass *var1;
    id<SomeProtocol> var2;
}
@end
@class SomeClass;
@协议SomeProtocol;//你可以申报这些
@接口MyClass{
SomeClass*var1;
id-var2;
}
@结束

我也有类似的问题,但有一个Swift协议。
@class Foo;

@interface Bar : Foo
// Will get error: attempting to use the forward class 'Foo' as superclass of 'Bar'
@end;
#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