Objective-C有反射吗?

发布于 2024-12-06 11:07:29 字数 57 浏览 7 评论 0原文

我正在研究Objective-C,我想知道它是否有反射的概念。到目前为止我找到的文档都没有描述反射。

I'm doing research about Objective-C, and I'd like to know if it has the concept of reflection. None of the documents I've found so far describes reflection.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

凹づ凸ル 2024-12-13 11:07:29

运行时参考中描述了运行时函数,不允许不仅查询类或实例的功能,还添加方法,甚至在运行时创建新类。我说这是一种非常动态的反射,基于 C 的语言通常无法使用它。 Mike Ash 的包装器 是围绕它的 Objective-C 包装器。同样,它甚至可以添加方法! Cocoa 的基类 NSObject 还为许多运行时函数提供了包装器,请参阅 NSObject 协议参考。例如,

     [foo respondsToSelector:@selector(bar:)];

     if([foo isKindOfClass:[NSString class]]){ ... } 

执行方法名称所示的操作。您甚至可以动态添加方法。例如,

   #import <Foundation/Foundation.h>
   #import <objc/runtime.h>

   @interface Foo:NSObject
   {
   }
   @end
   @implementation Foo
   -(void)sayHi
   {
        NSLog(@"Hi! from %@",NSStringFromSelector(_cmd));
   }
   +(BOOL)resolveInstanceMethod:(SEL)sel
   {
        Method method=class_getInstanceMethod(self,@selector(sayHi));
        class_addMethod(self,sel,method_getImplementation(method),method_getTypeEncoding(method));
        return YES;
   }
   @end

   int main(){
    NSAutoreleasePool*pool=[[NSAutoreleasePool alloc] init];
        Foo* foo=[[Foo alloc] init];
        [foo aeiou];
        [foo bark];
        [foo mew];
        [pool drain];
        return 0;
  }

这会产生输出

  Hi! from aeiou
  Hi! from bark
  Hi! from mew

其作用如下:

  1. SEL 是表示发送消息(或其他术语中的方法调用)的变量。
  2. Objective-C 运行时调用 resolveInstanceMethod :如果发送到实例的消息未在类中实现,则为类的
  3. 因此,在本例中,我只需将名为 sayHi 的预定义方法的实现复制到该方法的实现中。
  4. 在该方法中,您可以使用 _cmd 查看调用该方法时使用的选择器。因此,即使从单个 sayHi 实现中,我们也可以获得不同的输出。

一些标准 Cocoa 的实现(特别是 Key-Value-Coding、Key-Value-Observing 和 Core Data)使用运行时来动态修改类。

There are runtime functions described in Runtime Reference which allows not only querying for features of a class or an instance, but also adding a method, or even creating a new class at runtime. I say this is a very dynamic kind of reflection, which was not usually available to C-based languages. Mike Ash's wrappers is an Objective-C wrapper around that. Again, it can even add methods! The base class of Cocoa, NSObject, also provide wrappers for many of the runtime functions, see NSObject protocol reference. For example

     [foo respondsToSelector:@selector(bar:)];

     if([foo isKindOfClass:[NSString class]]){ ... } 

does what the method names say. You can even add a method on the fly. For example,

   #import <Foundation/Foundation.h>
   #import <objc/runtime.h>

   @interface Foo:NSObject
   {
   }
   @end
   @implementation Foo
   -(void)sayHi
   {
        NSLog(@"Hi! from %@",NSStringFromSelector(_cmd));
   }
   +(BOOL)resolveInstanceMethod:(SEL)sel
   {
        Method method=class_getInstanceMethod(self,@selector(sayHi));
        class_addMethod(self,sel,method_getImplementation(method),method_getTypeEncoding(method));
        return YES;
   }
   @end

   int main(){
    NSAutoreleasePool*pool=[[NSAutoreleasePool alloc] init];
        Foo* foo=[[Foo alloc] init];
        [foo aeiou];
        [foo bark];
        [foo mew];
        [pool drain];
        return 0;
  }

This produces the output

  Hi! from aeiou
  Hi! from bark
  Hi! from mew

What it does is as follows:

  1. SEL is the variable which represents the sent message (or method call, in the other terminology.)
  2. Objective-C runtime calls resolveInstanceMethod: of a class if a message sent to an instance is not implemented in the class
  3. So, in this case, I just copy an implementation of a predefined method called sayHi to that method's implementation.
  4. From the method, you can use _cmd to see what was the selector used in calling the method. So, even from a single sayHi implementation, we can get different output.

Some of the standard Cocoa's implementation (Key-Value-Coding, Key-Value-Observing and Core Data in particular) uses the runtime to dynamically modify the class.

血之狂魔 2024-12-13 11:07:29

是的,Objective-C 有反射(和抽象类)。这种反映是否符合您的需求是另一个问题。

Objective-C 中的反射对于 C 派生语言来说非常灵活。您可以询问一个类它实现了哪些方法,或者您可以修改和/或向现有类添加方法。您甚至可以动态创建新类或随时更改任何实例的类。

除了偶尔调用 respondsToSelector:conformsToProtocol: 之外,典型的 Objective-C 程序不会做任何事情(至少不会直接做)。虽然 Objective-C 是一种完全动态的、反射性的、面向对象的语言,但这并不意味着鼓励或通常使用这种模式。

您可能会发现我对这些问题的回答很有趣:

在 Objective C 中,如何通过反射找出方法的返回类型?

Objective-C 有标准库吗?

Smalltalk 运行时功能缺失在 Objective-C 上?

当然,运行时是 记录非常详细。就像语言一样。或者您可以阅读源代码

Yes, Objective-C has reflection (and abstract classes). Whether that reflection fits your needs or not is a different question.

Reflection in Objective-C is surprisingly flexible for a C derived language. You can ask a class what methods it implements or you can modify and/or add methods to existing classes. You can even create new classes on the fly or change the class of any instance at any time.

A typical Objective-C program does none of theses things (at least not directly) save for occasionally calling respondsToSelector: or conformsToProtocol:. While Objective-C is a fully dynamic, reflective, object oriented language, that doesn't mean that such patterns are encouraged or typically used.

You might find my answers to these questions interesting:

In Objective C, how to find out the return type of a method via reflection?

Does Objective-C have a Standard Library?

Smalltalk runtime features absent on Objective-C?

And, of course, the runtime is very well documented. As is the language. Or you could read the source.

几度春秋 2024-12-13 11:07:29

我想我不知道你在寻找反思的哪一方面。您是否正在寻找如何确定给定变量属于哪个类?如果是这样,请检查一下: Objective-C class ->字符串如:[NSArray className] -> @“NSArray”

// Get a object's class name
if ([NSStringFromClass([foo class]) compare:@"NSSomeObject"] == NSOrderedSame) {...}

// Does an object have a method
[foo respondsTo:@selector(method:)]

您是否正在寻找更多内容?

I guess I don't know what aspect of reflection you're looking for. Are you looking for how to determine which class a given variable is? If so, check this out: Objective-C class -> string like: [NSArray className] -> @"NSArray"

// Get a object's class name
if ([NSStringFromClass([foo class]) compare:@"NSSomeObject"] == NSOrderedSame) {...}

// Does an object have a method
[foo respondsTo:@selector(method:)]

Are you looking for more than just this?

-黛色若梦 2024-12-13 11:07:29

有很多方法它可以访问类的各种属性,并且可能“窥视”和“戳”某些对象内部。我从来没有玩过它们,我读过的一些书表明它们远非完美,但它们似乎确实提供了一些“反射”的能力,类似于 Java 概念。

There are a flock of methods that can access various properties of a class and, presumably, "peek" and "poke" at some object internals. I've never played with them, and a little reading that I've done suggests that they're far from perfect, but they do appear to offer some ability for "reflection", similar to the Java concept.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文