在Objective-C中编译成的@接口是什么?
当我在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
@接口时,例如:
@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];