2016-09-01 2 views
7

У меня есть MyClassA, который имеет свойство типа MyClassBвперед Декларация против #import когда подклассов

// 
// MyClassA.h 
// 

@interface MyClassA : NSObject 

@property (strong, nonatomic, readonly) MyClassB *myClassB; 

@end 

MyClassB имеет свойство myString.

// 
// MyClassB.h 
// 

@interface MyClassB : NSObject 

@property (copy, nonatomic, readonly) NSString *myString; 

@end 

У меня есть MyClassC, который нужно получить доступ к myString в его реализации.

Должен ли я -

а) Форвард Объявить MyClassB в MyClassA.h и #import "MyClassB.h" в MyClassC.m

или

б) #import MyClassB.h в MyClassA.h

ответ

2

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

Для этого примера я бы использовал @class для всех ваших объявлений свойств в ваших заголовочных файлах и #import MyClassB.h в файле MyClassC.m. Это позволит MyClassC знать обо всех свойствах MyClassB.

2

Рассматривая это с немного другого угла ... вам нужно решить, хотите ли вы, чтобы мир действительно знал о myClassB, являющемся собственностью MyClassA. Например, если вы можете только рекламировать это myString, которое может быть получено через MyClassA. Это изолирует другие классы от знания базовой реализации myString. Если вам не нужно выставлять MyClassB, вам следует скрыть его от «остальной части мира».

В этом случае вы бы изменить MyClassA.h следующим образом:

// 
// MyClassA.h 
// 

@interface MyClassA : NSObject 

@property (strong, nonatomic, readonly) NSString *myString; 

@end 

В MyClassA.m, вы могли бы сделать следующее.

// 
// MyClassA.m 
// 

#import "MyClassA.h" 
#import "MyClassB.h" 

@interface MyClassA() 

@property (strong, nonatomic) MyClassB *myClassB;; 

@end 

@implementation MyClassA 

// Other meaningful code omitted 

- (NSString *)myString { 
    return self.myClassB.myString; 
} 

@end 

Обратите внимание, что то, что я сделал здесь использовать анонимную категорию внутренне определить свойство для myClassB.

Главное, имеет ли смысл не подвергать MyClassB другим. Главное преимущество этого подхода - ваш код более податливый. Скажем, myString получает другой способ. Из другого класса или другого метода. Код, который должен потреблять myString, иммунизирован.

Если вам нужно разоблачить MyClassB, то вы можете использовать @class в соответствии с рекомендациями Tyler выше или #import MyClassB.h от MyClassA.h. Лучшие практики предписывают переслать объявление @class. Но время от времени удобство отсутствия необходимости запоминать много файлов в файле реализации может победить. Это ваша кодовая база, поэтому вы можете выбрать, какой из них лучше всего подходит для вас. Обычно я использую комбинацию из двух.

Смежные вопросы