名前でobjective-cクラスのインスタンスを作成しますか?


95

名前でクラスのインスタンスを作成することは可能ですか?何かのようなもの:

NSString* className = @"Car";
id* p = [Magic createClassByName:className];
[p turnOnEngine];

これがobjective-cで可能かどうかはわかりませんが、可能であるようですが、

回答:



38

NSClassFromString()クラス名を誤って入力したり、存在しないクラスを使用したりするリスクがあります。エラーが発生しても、実行時まではわかりません。代わりに、組み込みのObjective-CタイプClassを使用して変数を作成する場合、コンパイラーはクラスが存在することを確認します。

たとえば、あなたの.h

@property Class NameOfClass;

そしてあなたの中で.m

id object = [[NameOfClass alloc] init];

クラス名を誤って入力した場合、またはクラス名が存在しない場合は、コンパイル時にエラーが発生します。また、これはよりクリーンなコードだと思います。


行くぞ、バディ。2行を必要とし、動的ではないため、それが最良の答えであるかどうかは完全にはわかりませんが、まったく同じように賛成しています
Chris McCall

文字列の代わりに記号を使用したため、動的性が低いと言えるでしょう。ただし、コードを記述しているときに必要なクラスがわかっている場合は、タイプミスを避けるためにシンボルを使用することをお勧めします。
Simon Woodside

@sbwoodside:これはどのように機能しますか?試してみたところ、リンカから「アーキテクチャ用の未定義シンボル」を入手しました。
Lars Schneider

[[[self class] alloc] init];に変更します。他には何も必要ありません。
Nick Turner

OPの使用例は正当なものだけではありません。これは、オブジェクト階層をfile / memory-block / plist / whateverにシリアル化するためのベースです。多くの場合、インスタンス化する必要があるクラスを事前に知らないことがあります。私のユースケースは、ガジリオンの「NSValueTransformer」を「登録」するという退屈な必要性であり、[NSValueTransformer setValueTransformer:MyTransformerA alloc] init] forName:@ "MyTransformerA"]を複製する代わりに; 40回-トランスフォーマー名のNSArrayをスキャンし、文字列から作成/登録します。
Motti Shneor 2018年

8

あなたはなしでのObjective-Cで作業している場合はNeXTstepOS XiOSGNUstepなど)をシステムまたはあなただけのこのメソッドはきれいだと思う、あなたは利用することができるObjective-C言語のランタイムライブラリのAPIを。下Objective-C 2.0

#import <objc/runtime.h>
//Declaration in the above named file
id objc_getClass(const char* name);
//Usage
id c = objc_getClass("Object");
[ [ c alloc ] free ];

Objective-C(1.0または名前のないバージョン)では、以下を利用します。

#import <objc/objc-api.h>
//Declaration within the above named file
Class objc_get_class( const char* name);
//Usage
Class cls = objc_get_class( "Test" );
id obj = class_create_instance( cls );
[ obj free ];

私は1.0バージョンをテストしていませんが、2.0現在運用中のコードで関数を使用しました。私は個人的に利用信じる2.0:可能な場合、それはより少ないスペース消費として機能するNS機能よりもクリーンであるthe length of the name in bytes + 1 ( null terminator )対2.0 APIのためthe sum of two pointers (isa, cstring)size_t length (cstring_length)length of the string in bytes + 1のためのNeXTSTEPAPI。


2
@interface Magic : NSObject
+ (id)createInstanceOfClass:(Class)classe;
@end

@implementation Magic

+ (id)createInstanceOfClass:(Class)classe
{
    return [[classe alloc] init];
}

@end

それを使用するには:

Car *car = [Magic createInstanceOfClass:[Car class]];
[car engineTurnOn];
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.