Objective-C: Директива @class перед @interface?

В чем разница между этими двумя объявлениями классов? Я не понимаю, почему здесь используется @class. Благодарю.

<code>@class TestClass;

@interface TestClass: UIView {
    UIImage *image1;
    UIImage *image2;
}
</code>

а также

<code>@interface TestClass: UIView {
    UIImage *image1;
    UIImage *image2;
}
</code>

Ответы на вопрос(4)

Согласно ответу Мэтта, абсолютно нет смысла@class декларация в вашем коде.@class forward определяет класс таким образом, чтобы компилятор впоследствии знал, к какому типу модуля вы обращаетесь. Поскольку Objective-C практически не содержит типов во время выполнения, часто это все, что на самом деле нужно знать компилятору & # x2014; достаточно, чтобы отличить вещь от атомного значения C.

Я собираюсь сделать удар в темноте и сказать, что, поскольку переменные экземпляра объявлены в@interface Вы просматриваете старый код. Поскольку это старый код,@class вероятно, раньше был где-то еще (например, между ними был объявлен протокол делегата) и только что оказался безвредным.

Решение Вопроса

@class существует, чтобы нарушить круговые зависимости. Скажем, у вас есть классы А и Б.

@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 безвреден, но совершенно ненужен.

 05 июл. 2013 г., 15:25
Я хотел бы дать еще один +1 только для «курицы, встретить яйцо»;
 21 мая 2014 г., 18:19
Кстати, он возвращается кid оценка.
 01 июн. 2014 г., 02:11
@JoshValdivieso Вы по-прежнему быстро получите циклические зависимости, и общая схема состоит в том, чтобы минимизировать количество импортов в заголовочном файле, поскольку это значительно сокращало время компиляции (что не так часто в наши дни и в наши дни). предварительно скомпилированные заголовки).
 30 мая 2014 г., 22:01
Существуют ли конкретные причины, по которым некоторые люди@class в их файле .h, а затем импортировать необходимые файлы заголовков в свои файлы .m, а другие могут просто импортировать файл .h в файл заголовков текущих классов? Просто любопытно, спасибо. @bbum
@class TestClass;

Это просто объявляет, что «класс TestClass будет определен».

В этом случае (тот, который вы вставили) это не имеет никакого эффекта, поэтому они одинаковы.

Однако в случае, если вы собираетесь определить протокол, который будет использовать имя вашего класса (например, в качестве типа параметров, передаваемых делегату), вам нужно будет объявить@class TestClass до определения протокола, так как ваш класс еще не определен.

В общем, если вам нужно упомянуть имя вашего класса до того, как определение класса будет сделано, вам нужно будет выполнить@class объявление первым

 10 февр. 2015 г., 23:29
Я видел эту реализацию наиболее - до протоколов. Спасибо, что поделился!

@class очень удобен, когда вам нужно определить протокол для объекта, который обычно будет взаимодействовать с объектом, интерфейс которого вы также определяете. Используя @class, вы можете сохранить определение протокола в заголовке вашего класса. Этот шаблон делегирования часто используется в Objective-C и часто предпочтительнее, чем определение обоих "MyClass.h". и & quot; MyClassDelegate.h & quot ;. Это может вызвать некоторые проблемы с импортом

@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];

}

Ваш ответ на вопрос