【问题标题】:Forward Declaration vs #import when subclassing子类化时的前向声明与#import
【发布时间】:2016-09-01 20:17:23
【问题描述】:

我有MyClassA,它的属性类型为MyClassB

//
//  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

我应该 -

a) 在MyClassA.h#import "MyClassB.h"MyClassC.m 中转发声明MyClassB

b) #import MyClassB.h in MyClassA.h

【问题讨论】:

    标签: objective-c import include forward-declaration


    【解决方案1】:

    一般来说,您应该尽可能在头文件中使用@class 转发声明。您可能不想这样做的唯一一次是当您从超类继承或声明协议一致性时,因为编译器需要知道该类或协议中发生了什么。

    对于这个例子,我会在你的头文件中对所有属性声明使用@class,在你的 MyClassC.m 文件中使用#import MyClassB.h。这将允许 MyClassC 了解 MyClassB 上的所有属性。

    【讨论】:

      【解决方案2】:

      从稍微不同的角度来看...您需要决定是否希望全世界真正了解myClassBMyClassA 的属性。例如,如果您可能只想宣传可以通过MyClassA 获得的myString。这使其他类不知道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,那么您可以使用上面Tyler 推荐的@class 或MyClassA.h 中的#import MyClassB.h。最佳实践规定前向声明@class。但有时不必记住在实现文件中导入大量文件的便利可能会胜出。这是您的代码库,因此您可以选择最适合您的代码库。我通常将两者结合使用。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-04-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-05-08
        • 2010-10-16
        • 2018-06-05
        • 2016-01-17
        相关资源
        最近更新 更多