2011-09-26 40 views
19

我正在研究Objective-C,我想知道它是否有反射的概念。我迄今發現的文件都沒有描述反思。Objective-C是否有反思?

+0

請參閱http://en.wikipedia.org/wiki/Objective-C –

+1

Objective-C具有比Java更強大的反射能力。您可以從[Apple的Objective-C運行時編程指南]瞭解更多信息。(http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Introduction/Introduction.html#//apple_ref/doc/uid/TP40008048) – venj

+0

感謝「ott」和「venj」。 –

回答

24

Runtime Reference中描述的運行時功能不僅可以查詢類或實例的功能,還可以添加方法,甚至可以在運行時創建新類。我說這是一種非常動態的反思,對於基於C的語言來說通常是不可用的。 Mike Ash's wrappers是一個圍繞它的Objective-C包裝。再次,它甚至可以添加方法!可可的基類,NSObject,也爲許多運行時功能提供包裝,參見NSObject protocol reference。例如,

 [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:類因此,在這種情況下,我只是將一個名爲sayHi的預定義方法的實現複製到該方法的實現中。
  3. 從該方法中,您可以使用_cmd來查看調用該方法時使用的選擇器。所以,即使從一個單一的sayHi實現,我們可以得到不同的輸出。

一些標準的Cocoa實現(特別是鍵值編碼,鍵值觀察和核心數據)使用運行時動態修改類。

1

我想我不知道你在找什麼方面的反射。你在尋找如何確定給定變量是哪個類?如果是這樣,檢查了這一點: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:)] 

您正在尋找的不僅僅是這一點?

+0

哦!我的經理需要研究關於抽象類和Objetive-C中的反射。我試圖找出但沒有結果,所以我必須問大家:(。 P/S:非常感謝。 –

+0

呃?是否與你的工作有關?你需要付給我們部分工資:) – Yuji

+0

@ Yuji。呵呵 。好的:P –

1

有一堆methods可以訪問一個類的各種屬性,大概是在一些對象內部的「偷看」和「戳」。我從來沒有和他們一起玩過,我所做的一些小小的閱讀表明他們遠非完美,但他們似乎提供了一些「反思」的能力,類似於Java概念。

+0

非常感謝:) –

+0

你有任何想法如何設置實際屬性,一旦你找到它使用反射?我在這裏有一個問題:http://stackoverflow.com/q/25538890/1735836 – Patricia

11

是的,Objective-C有反射(和抽象類)。這種反射是否符合你的需求是一個不同的問題。

Objective-C中的反射對於C派生語言來說是非常靈活的。你可以問一個類它實現了什麼方法,或者你可以修改和/或添加方法到現有的類。您甚至可以隨時創建新類或隨時更改任何實例的類。

典型Objective-C的程序確實沒有任何東西論文(至少不直接地)保存偶爾主叫respondsToSelector:conformsToProtocol:。雖然Objective-C是一種完全動態的,反思的,面向對象的語言,但這並不意味着鼓勵或通常使用這種模式。

你可能會發現我的這些問題的答案有趣:

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?

,當然,運行時間是very well documented。正如the language。或者你可以read the source

+0

你有什麼想法如何設置實際屬性,一旦你找到它使用反射?我在這裏有一個問題:http://stackoverflow.com/q/25538890/1735836 – Patricia