代码之家  ›  专栏  ›  技术社区  ›  jbrennan

Objective中的循环#导入/@类问题

  •  0
  • jbrennan  · 技术社区  · 16 年前

    我将用一个例子来恰当地说明我的困惑。我不能完全相信这一点。

    UIViewController 及其子类, UINavigationController UIVC 有一个ivar类型 UINav ,并绕过他们使用的循环导入问题 @class UINavigationController . 我想他们会的 #import "UINavigationController UIViewController.m (或诸如此类)。

    UIViewController 然后了解中声明的方法 导航控制器 ? 从UIViewController子类内部可以调用 [self.navigationController popViewController] ,但这种方法是如何知道的?

    我唯一的想法是 导航控制器 必须单独导入到每个子类(可能在前缀中?)

    有什么想法吗?

    2 回复  |  直到 16 年前
        1
  •  1
  •   NSResponder    16 年前

        2
  •  0
  •   TechZen    16 年前

    A.h级

    #import <Foundation/Foundation.h>
    
    @class ClassB;
    @interface ClassA : NSObject {
        ClassB *bClass;
    }
    @property(nonatomic, retain)  ClassB *bClass;
    
    @end
    

    A.m级

    #import "ClassA.h"
    #import "ClassB.h"
    
    @implementation ClassA
    @synthesize bClass;
    
    -(ClassB *) bClass{
        return [[ClassB alloc] init];
    }
    @end
    

    #import <Foundation/Foundation.h>
    
    @class ClassA;
    @interface ClassB : NSObject {
        ClassA *aClass;
        NSString *name;
    }
    @property(nonatomic, retain)  ClassA *aClass;
    @property(nonatomic, retain)  NSString *name;
    
    @end
    

    B.m级

    #import "ClassB.h"
    #import "ClassA.h"
    
    @implementation ClassB
    @synthesize aClass;
    @synthesize name;
    
    -(NSString *) name { return @"steve";}
    @end
    

    C.h类

    #import <Foundation/Foundation.h>
    #import "ClassA.h"
    
    @interface ClassC : ClassA {
    
    }
    
    @end
    

    #import "ClassC.h"
    @implementation ClassC
    
    @end
    

    #import "ClassC.h"
    ...
    ClassC *c=[[ClassC alloc] init];
    NSLog(@"c %@",[[c bClass] name]); //prints "c steve"
    

    子类包含导入到其超级类实现文件中的头。

    从评论中:

    (未在此处导入ClassA.h)。信息技术 不会编译

    A.h级

    #import <Foundation/Foundation.h>
    
    #define aMacro 5
    
    @class ClassB;
    @interface ClassA : NSObject {
        ClassB *bClass;
    }
    @property(nonatomic, retain)  ClassB *bClass;   
    @end
    

    C.h类

    #import <Foundation/Foundation.h>
    #import "ClassA.h"
    
    @interface ClassC : ClassA {
    }
    -(void) logMacro;
    @end
    

    C.m类

    #import "ClassC.h"
    
    @implementation ClassC
    -(void) logMacro{
        NSLog(@"aMacro=%d",aMacro);
    }//-------------------------------------(void) logMacro------------------------------------
    @end
    

    运行时:

    #import "ClassC.h" //the only header imported of the three classes ./////////
    ...
    ClassC *c=[[ClassC alloc] init];
    NSLog(@"c %@",[[c bClass] name]);
    [c logMacro]; //prints 5
    

    ClassC不知道ClassA.m中定义的宏,但这是因为在实现中定义的宏实际上不是类的逻辑部分。ClassA也不“知道”宏。这样的宏不在类的名称空间中,它只是由编译器执行的简单文本替换。ClassC不知道这样的替换,就像它知道ClassA在它的一个方法中的某个地方使用了实际的“5”一样。ClassC不能固有这样一个宏,因为它没有固有的属性。

    ClassC知道在ClassA中定义的宏,因为编译器生成的ClassC的真正逻辑头是导入创建的链中所有头的并集。C类

    ClassC和ClassA了解ClassB的方式相同。@class指令使编译器查找ClassB的定义,并在ClassA.m中找到它。在幕后没有秘密导入大量头文件。这是家长们提出的问题。