これは客観的な質問です。インスタンス化されたオブジェクトなしでメソッドを呼び出す方法
私はオブジェクト内のメソッドを呼びたいと思いますが、オブジェクトのインスタンス化はありません。これは可能ですか?
呼び出すメソッドはクラスメソッドではありません。
これは客観的な質問です。インスタンス化されたオブジェクトなしでメソッドを呼び出す方法
私はオブジェクト内のメソッドを呼びたいと思いますが、オブジェクトのインスタンス化はありません。これは可能ですか?
呼び出すメソッドはクラスメソッドではありません。
おそらく、単純なC関数が必要になるだけです。クラスメソッドを必要とせず、インスタンスメソッドを必要としない場合は、唯一のオプションです。 Objective-CでC関数を使用するのを恐れないでください。すべての技術がその場所を持っています。
方法がstatic
でない限り、これを行うことはできません。 Objective-Cのstatic
ルーチンの先頭には+
が追加されます。
+ (id)alloc; // static - an NSObject instance is not required
- (NSString*)description; // nonstatic - an NSObject instance is required
一つはそうのようなそれぞれの呼び出しを行います:
NSObject* result = [NSObject alloc];
NSString* desc = [result description];
あなたは存在しないオブジェクトのメソッドを呼び出すことはできません例えば、NSObjectのは、(多くの中で)これら2つのルーチンを提供します。しかし、クラスのメソッドをインスタンス化しても、そのクラスのインスタンス化されたオブジェクトを呼び出すことはできません。 (これはallocが@ fbreretonの答え - クラスメソッドです)。
クラスメソッドは、 - ではなく+で宣言され定義され、インスタンスではなくクラスで呼び出され、クラス内の自己変数またはインスタンス変数にアクセスできません。
これをこの言語の「静的メソッド」と結びつけますか? –
@ d03boy Objective-Cでは、これらの「クラス」メソッドを呼びますが、他の言語で使用される静的メソッドと機能的に同等です。 –
オブジェクトCクラスはインスタンスと同じように静的メソッド以上です。たとえば、 - [NSArray配列]メソッドは、受信側のインスタンスを返すという点で動的です。[NSMutableArray array]の結果、配列は変更可能ですが、NSMutableArrayはそのメソッドをオーバーライドする必要はありません。これは、次のようなメソッドを実装することで実現できます: "return [[[self alloc] init] autorelease]"。これは、 '自己'がNSMutableArray、もう一方がNSArrayであるため動作します。したがって、objective-cでは、多態的なクラスメソッドを持つことができます。 –
インスタンスメソッドは、実際にはクラスメソッド(インスタンス変数にはアクセスしない)であれば、実際にインスタンスなしで呼び出すことができます。あなたは、インスタンスメソッドは、それが(+alloc
またはclass_getInstanceSize()
プラスmalloc()
のいずれかを使用して)で動作するようにするためにメモリを割り当てることによって、インスタンス変数にアクセスした場合でも、それは仕事を得ることができ
/*
Compile with:
gcc -framework Foundation inst_method_without_inst.m -o inst_method_without_inst
*/
#import <Foundation/Foundation.h>
#import <objc/runtime.h>
@interface Foo : NSObject {
}
- (BOOL)doSomethingWithThis:(NSString *)this;
@end
@implementation Foo
- (BOOL)doSomethingWithThis:(NSString *)this {
NSLog(@"Look, it's this: %@", this);
return YES;
}
@end
typedef BOOL (*my_sel_t)(id, SEL, NSString *);
int
main(void) {
Class cls = [Foo class];
SEL my_sel = @selector(doSomethingWithThis:);
Method m = class_getInstanceMethod(cls, my_sel);
// You could also use +[NSObject instanceMethodForSelector:] to get |m|,
// since |cls| is a kind of NSObject.
my_sel_t f = (my_sel_t)method_getImplementation(m);
BOOL result = f(nil, my_sel, @"Hello from an instanceless instance method invocation!");
NSLog(@"result: %d", (int)result);
return EXIT_SUCCESS;
}
、そのメモリへのポインタを渡すよう:ここでは例ですnil
ではなく、実装の最初のid
引数。
これはエクササイズとして面白いですが、クラスをインスタンス化して標準のメッセージング構文とコンパイラのサポートを使用するだけの理由はないと思います。実際、ここで[(Foo *)nil doSomethingWithThis:@"BOO!"]
を行うことができなかった唯一の理由は、objc_msgSend()
の特殊ケースのメッセージをnil
に変換した結果、NO
が返され、何も起こらないということです。
Upvotingこれは最も技術的に正しいことに加えて、これは非常に教育的だったからです! –
NIT-ピッククリスの用語に申し訳ありませんが、我々はないコールのObjective-Cでオブジェクトのメソッドを実行する、我々はオブジェクトにメッセージを送る。メッセージを送信すると、ランタイムは適切なメソッドをルックアップして呼び出します。その区別は重要です。
どのメソッドを呼び出すか教えていただけますか? –