Objective-C : @interface 전에 @class 지시문? 이해하지 못합니다. 감사. @class TestClass; @interface TestClass:

이 두 클래스 선언의 차이점은 무엇입니까? @class가 여기에서 사용되는 이유를 이해하지 못합니다. 감사.

@class TestClass;

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

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



답변

@class순환 종속성을 깨기 위해 존재합니다. 클래스 A와 B가 있다고 가정합니다.

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

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

치킨; Egg를 만나십시오. A의 인터페이스는 정의되는 B에 의존하고 그 반대의 경우도 마찬가지이기 때문에 컴파일 할 수 없습니다.

따라서 @class다음 을 사용하여 수정할 수 있습니다 .

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

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

@class컴파일러에게 그러한 클래스가 어딘가에 존재하므로 해당 클래스의 인스턴스를 가리 키도록 선언 된 포인터가 완벽하게 유효 함을 효과적으로 알립니다. 그러나 @class컴파일러에서 사용할 수있는 추가 메타 데이터가 없기 때문에 유형이로만 정의 된 인스턴스 참조에 대한 메서드를 호출 할 수 없습니다 (호출 사이트를 id또는 아니).

귀하의 예에서는 @class무해하지만 완전히 불필요합니다.


답변

@class TestClass;

이것은 단지 “클래스 TestClass가 정의 될 것입니다”를 선언합니다.

이 경우 (당신이 붙여 넣은 것) 이것은 전혀 효과가 없으므로 이것들은 동일합니다.

그러나 클래스 이름을 사용하는 프로토콜을 정의하려는 경우 (예 : 위임에 전달되는 매개 변수 유형) @class TestClass클래스가 아직 정의되지 않았으므로 프로토콜 정의 전에 선언 해야합니다.

일반적으로 클래스 정의가 이루어지기 전에 클래스 이름을 언급해야하는 경우 @class먼저 선언 을 발행해야합니다.


답변

Matt의 답변에 따르면 @class코드 의 선언에 대한 의미가 전혀 없습니다 . @classforward는 클래스를 정의하여 컴파일러가 사용자가 참조하는 일반적인 종류의 단위를 나중에 알 수 있도록합니다. Objective-C는 런타임에 유형이 거의 없기 때문에 컴파일러가 실제로 알아야하는 모든 것입니다. 원자 C 값과 구별하기에 충분합니다.

나는 어둠 속에서 찔러서 인스턴스 변수가 선언되어 있기 때문에 @interface오래된 코드를보고 있다고 말할 것입니다 . 오래된 코드이기 때문에 @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

그런 다음 클래스를 사용할 때 클래스의 인스턴스를 만들고 단일 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];

}


답변