Objective c 目标C:@接口之前的@class指令?

Objective c 目标C:@接口之前的@class指令?,objective-c,syntax,Objective C,Syntax,这两个类声明之间有什么区别?我不明白这里为什么使用@class。谢谢 @class TestClass; @interface TestClass: UIView { UIImage *image1; UIImage *image2; } 及 这只是声明“将定义类TestClass” 在这种情况下(你粘贴的那个),这没有任何效果,所以它们是一样的 但是,如果要定义使用类名的协议(例如,作为传递给委托的参数类型),则需要在协议定义之前声明@class TestClass,因为尚

这两个类声明之间有什么区别?我不明白这里为什么使用@class。谢谢

@class TestClass;

@interface TestClass: UIView {
    UIImage *image1;
    UIImage *image2;
}

这只是声明“将定义类TestClass”

在这种情况下(你粘贴的那个),这没有任何效果,所以它们是一样的

但是,如果要定义使用类名的协议(例如,作为传递给委托的参数类型),则需要在协议定义之前声明
@class TestClass
,因为尚未定义类


一般来说,如果您需要在定义类之前提及您的类名,您需要首先发布
@class
声明

,根据Matt的回答,代码中的
@class
声明毫无意义
@class
forward定义了一个类,以便编译器随后知道您所引用的单元的一般类型。由于Objective-C在运行时几乎是无类型的,这通常是编译器实际需要知道的全部内容——仅足以将其与原子C值区分开来


我想说的是,由于实例变量是在
@接口中声明的,所以您看到的是一些旧代码。因为它是旧代码,
@class
可能以前在其他地方(例如,中间声明了一个委托协议),结果只是无害地搁浅了。
@class
的存在打破了循环依赖关系。假设你有A班和B班

@interface A:NSObject
- (B*)calculateMyBNess;
@end

@interface B:NSObject
- (A*)calculateMyANess;
@end
鸡;遇到鸡蛋。这永远无法编译,因为A的接口依赖于B的定义,反之亦然

因此,可以通过使用
@class
:

@class B;
@interface A:NSObject
- (B*)calculateMyBNess;
@end

@interface B:NSObject
- (A*)calculateMyANess;
@end
@class
有效地告诉编译器这样一个类存在于某个地方,因此,声明指向所述类实例的指针是完全有效的。但是,您无法对类型仅定义为
@class
的实例引用调用方法,因为编译器没有可用的其他元数据(我不记得它是否将调用站点还原为通过
id
进行的调用)


在您的示例中,
@class
是无害的,但完全没有必要。

@class在您需要为对象定义协议时非常方便,该对象通常会与您正在定义接口的对象交互。使用@class,您可以将协议定义保留在类的头中。这种委托模式通常用于Objective-C,并且通常比同时定义“MyClass.h”和“MyClassDelegate.h”更可取。这可能会导致一些令人困惑的导入问题

@class MyClass;

@protocol MyClassDelegate<NSObject>

- (void)myClassDidSomething:(MyClass *)myClass
- (void)myClass:(MyClass *)myClass didSomethingWithResponse:(NSObject *)reponse
- (BOOL)shouldMyClassDoSomething:(MyClass *)myClass;
- (BOOL)shouldMyClass:(MyClass *)myClass doSomethingWithInput:(NSObject *)input

@end

// MyClass hasn't been defined yet, but MyClassDelegate will still compile even tho
// params mention MyClass, because of the @class declaration.
// You're telling the compiler "it's coming. don't worry".
// You can't send MyClass any messages (you can't send messages in a protocol declaration anyway),
// but it's important to note that @class only lets you reference the yet-to-be-defined class. That's all.
// The compiler doesn't know anything about MyClass other than its definition is coming eventually.

@interface MyClass : NSObject

@property (nonatomic, assign) id<MyClassDelegate> delegate;

- (void)doSomething;
- (void)doSomethingWithInput:(NSObject *)input

@end
@class-MyClass;
@协议MyClassDelegate
-(void)MyClassDidThings:(MyClass*)MyClass
-(void)myClass:(myClass*)myClass做了一些有响应的事情:(NSObject*)响应
-(BOOL)应该MyClassDoSomething:(MyClass*)MyClass;
-(BOOL)应该MyClass:(MyClass*)MyClass doSomethingWithInput:(NSObject*)输入
@结束
//MyClass尚未定义,但MyClassDelegate仍将编译
//参数提到MyClass,因为@class声明。
//你告诉编译器“它来了,别担心”。
//您不能发送MyClass任何消息(无论如何也不能在协议声明中发送消息),
//但需要注意的是,@class只允许引用尚未定义的类。这就是全部。
//编译器对MyClass一无所知,只知道它的定义即将到来。
@接口MyClass:NSObject
@属性(非原子,赋值)id委托;
-(无效)剂量测定;
-(void)doSomethingWithInput:(NSObject*)输入
@结束
然后,当您使用该类时,您既可以创建该类的实例,也可以使用单个import语句实现该协议

#import "MyClass.h"

@interface MyOtherClass()<MyClassDelegate>

@property (nonatomic, strong) MyClass *myClass;

@end

@implementation MyOtherClass

#pragma mark - MyClassDelegate Protocol Methods

- (void)myClassDidSomething:(MyClass *)myClass {

    NSLog(@"My Class Did Something!")

}

- (void)myClassDidSomethingWithResponse:(NSObject *)response {

    NSLog(@"My Class Did Something With %@", response);

}

- (BOOL)shouldMyClassDoSomething {

    return YES;

- (BOOL)shouldMyClassDoSomethingWithInput:(NSObject *)input {

    if ([input isEqual:@YES]) {

        return YES;

    }

    return NO;

}


- (void)doSomething {

    self.myClass = [[MyClass alloc] init];
    self.myClass.delegate = self;
    [self.myClass doSomething];
    [self.myClass doSomethingWithInput:@0];

}
#导入“MyClass.h”
@接口类()
@属性(非原子,强)MyClass*MyClass;
@结束
@MyOtherClass的实现
#pragma标记-MyClassDelegate协议方法
-(void)MyClassDidThings:(MyClass*)MyClass{
NSLog(@“我的班级做了些什么!”)
}
-(void)myClassDidSomethingWithResponse:(NSObject*)响应{
NSLog(@“我的班级用%@”做了一些事情”,回复);
}
-(BOOL)我的班级应该做些什么{
返回YES;
-(BOOL)应该MyClassDoSomethingWithinput:(NSObject*)输入{
如果([输入相等:@YES]){
返回YES;
}
返回否;
}
-(无效)剂量{
self.myClass=[[myClass alloc]init];
self.myClass.delegate=self;
[self.myClass doSomething];
[self.myClass doSomethingWithInput:@0];
}

我希望我能给另一个+1,只是为了“鸡,遇到蛋”顺便说一句,它会恢复到
id
评估。有没有特别的原因,为什么有些人把
@class
放在他们的.h文件中,然后在他们的.m文件中导入必要的头文件,而其他人可能只在当前的class头文件中导入.h文件?只是好奇,谢谢@bbum@JoshValdivieso您仍然会很快得到循环依赖,一般的模式是最小化头文件中导入的数量,因为它用于显著减少编译时间(在今天和预编译头的时代,情况并非如此).我在协议之前见过最多的实现。谢谢分享!
@class MyClass;

@protocol MyClassDelegate<NSObject>

- (void)myClassDidSomething:(MyClass *)myClass
- (void)myClass:(MyClass *)myClass didSomethingWithResponse:(NSObject *)reponse
- (BOOL)shouldMyClassDoSomething:(MyClass *)myClass;
- (BOOL)shouldMyClass:(MyClass *)myClass doSomethingWithInput:(NSObject *)input

@end

// MyClass hasn't been defined yet, but MyClassDelegate will still compile even tho
// params mention MyClass, because of the @class declaration.
// You're telling the compiler "it's coming. don't worry".
// You can't send MyClass any messages (you can't send messages in a protocol declaration anyway),
// but it's important to note that @class only lets you reference the yet-to-be-defined class. That's all.
// The compiler doesn't know anything about MyClass other than its definition is coming eventually.

@interface MyClass : NSObject

@property (nonatomic, assign) id<MyClassDelegate> delegate;

- (void)doSomething;
- (void)doSomethingWithInput:(NSObject *)input

@end
#import "MyClass.h"

@interface MyOtherClass()<MyClassDelegate>

@property (nonatomic, strong) MyClass *myClass;

@end

@implementation MyOtherClass

#pragma mark - MyClassDelegate Protocol Methods

- (void)myClassDidSomething:(MyClass *)myClass {

    NSLog(@"My Class Did Something!")

}

- (void)myClassDidSomethingWithResponse:(NSObject *)response {

    NSLog(@"My Class Did Something With %@", response);

}

- (BOOL)shouldMyClassDoSomething {

    return YES;

- (BOOL)shouldMyClassDoSomethingWithInput:(NSObject *)input {

    if ([input isEqual:@YES]) {

        return YES;

    }

    return NO;

}


- (void)doSomething {

    self.myClass = [[MyClass alloc] init];
    self.myClass.delegate = self;
    [self.myClass doSomething];
    [self.myClass doSomethingWithInput:@0];

}