Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Objective-C中编译成的@接口是什么?_Objective C - Fatal编程技术网

在Objective-C中编译成的@接口是什么?

在Objective-C中编译成的@接口是什么?,objective-c,Objective C,当我在Objective-C中创建一个@接口时,例如: @interface MyClass : NSObject { @private } @end 它在编译时成为“某物”。例如,我可以做: [MyClass class] 或附加静态方法等 我无法执行“元”操作,例如: - (void)doSomethingWithInterface:(id)myInterface { NSLog(@"myInterface = %@", myInterface); Class a

当我在Objective-C中创建一个
@接口时,例如:

@interface MyClass : NSObject {
   @private

}
@end
它在编译时成为“某物”。例如,我可以做:

[MyClass class]
或附加静态方法等

我无法执行“元”操作,例如:

- (void)doSomethingWithInterface:(id)myInterface
{
    NSLog(@"myInterface = %@", myInterface);
    Class aClass = [myInterface class];
}

我可以传递一个类,但是如果我可以传递接口,它会更干净。那么…编译时接口会变成什么?有没有医生能解释这一点?我可以用接口做这样的“元”事情吗,或者接口的类对象本质上做了所有这些事情吗?

很确定您对Objective-C中的接口实际上是什么感到困惑。接口只是类的数据类型和方法的声明。Objective-C模拟到Java接口是协议

“我当然可以通过一门课……”你刚刚回答了自己的问题。因为接口创建的是它的类!所以

- (void)doSomethingWithClass:(Class)aClass {
  NSLog(@"class == %@", aClass);
}
通过使用

[obj doSomethingWithClass:[obj class]];
如果你真的想传递协议,下面是你要做的。假设你有一个协议

@protocol Foldable <NSObject>
+ (id <Foldable>)unit;
- (id <Foldable>)append:(id <Foldable>)object;
@end
您可以通过以下方式将协议传递到该方法:

[obj doSomethingWithProtocol:@protocol(Foldable)];
如您所见,虽然您通过向Objective-C类型标识符发送
+class
来传递类,但是您通过使用
@protocol()
指令来传递协议

编辑:更多信息

明确地说,接口只是编译器的一条指令。你不能去“抓取”一个界面并用它做些什么。但该接口会导致一些事情发生:

  • 它会在编译的程序中生成一个结构;此结构包含类的实例变量及其超类的实例变量
  • 它使与该结构关联的类型名能够接受Objective-C消息(如
    +class
    或其上定义的任何其他类方法);它实际上指向一个元类对象
  • 第二点可能有点混乱,但也很有趣。您被告知类是Objective-C中的对象,这基本上是正确的。但这可能会让你想知道为什么以下不可能:

    [self doSomethingWithClass:NSObject];
    
    你无法做到这一点的原因与你无法期望以下事情起作用的原因相同:

    [self doSomethingWithType:int];
    
    因为事实证明类标识符(如
    NSObject
    )实际上只是结构类型名称,但有一点扭曲:它们也可以接收消息。因此,如果你使用ObjuleC类作为C++中的模板参数,你可以向它发送消息!p>
    template <typename T>
    void something_crazy() {
      NSLog(@"object: %@", [[T new] autorelease]);
    }
    
    something_crazy<NSArray>();
    
    模板
    使疯狂的东西无效{
    NSLog(@“object:%@,[[T new]autorelease]);
    }
    疯狂的事;
    

    所以这是一个非常冗长的方法来回答你的最后一个问题,编译后接口会变成什么类型。接口本身在编译后的任何时候都不会变成任何东西,但会生成一种特殊的pimped结构,它接受充当元类的消息。

    接口是类的接口。因此,它规定了命名类的许多属性。接口不是独立的实体;接口和类之间有一个显式的1:1映射。所以我不清楚你想要实现什么。你能解释一下为什么你认为传递接口会更干净吗

    如果您正在寻找一个允许许多类实现相同接口的抽象,那么您正在寻找协议。声明为由类实现的协议是其运行时信息的一部分。如果需要,您可以找到协议中包含的方法。但是,由于没有1:1映射,您不能按照自己的意愿从协议转到类

    编辑:我想我现在更了解你了(为我理解的慢道歉)。你的意思是,假设:

    @interface SomeClass
    {
        // ...whatever...
    }
    
    // ... whatever...
    
    @end
    
    /* Elsewhere: */
    - (void)doThingWithClass:(Class)class
    {
       // do something
    }
    
    您不明白为什么必须使用:

    [instanceOfSomething doThingWithClass:[SomeClass class]];
    
    而不是:

    [instanceOfSomething doThingWithClass:SomeClass];
    
    原因是“SomeClass”不是一个抽象符号,只有编译器在编译时才能理解,它是一个类的实际实例(从技术上讲,它是一个元类),在运行时出现在内存中。这就是类方法的工作原理,例如

    [SomeClass doSpecialThing];
    
    或:


    编译器不能仅仅猜测您指的是类,而不是实例。因此,您可以使用“Class”消息从实例中获取类。可能(Cocoa with Love的“什么是Objective C中的元类?”)会有所帮助。

    类是对象,所以你可以说:

    Class *someClass = [myObject class];
    
    现在,someClass是指向myObject所属类的指针。你可以写

    [foo doSomethingWithClass:someClass];
    
    您正在传入类本身——编译
    @接口SomeClass:NSObject…
    部分时创建的东西


    正如前面有人所说,不要将Objective-C的@interface指令与Java接口混淆。Objective-C的协议类似于Java的接口@接口类似于Java的“class”关键字。

    您可能正在考虑@protocol.Hi Black Frog!谢谢,但不,我熟悉@protocol,这更多的是关于接口编译成什么。喂,接口类型的对象?嗨,乔纳森,谢谢。这是一个非常令人困惑的问题。为了澄清,我理解了协议和类之间的区别。我知道Objective-C协议类似于java接口。但你是对的,我不明白Obj-C中的接口到底是什么所以你是说这是一个类的“声明”。因此,我试图理解一旦编译程序,该声明是如何体现的。我现在正在按照你说的做:[obj doSomethingWithClass:[obj class]];我想我很好奇在编译时接口会变成什么类型?Chris,我已经添加了一些关于编译后接口会发生什么的更多信息。我赞扬你提出这个问题!对于初学者来说,很多错误的术语会使事情变得非常复杂。乔纳森,你已经回答了我的问题
    Class *someClass = [myObject class];
    
    [foo doSomethingWithClass:someClass];