이름으로 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];

클래스 이름을 잘못 입력했거나 존재하지 않으면 컴파일 타임에 오류가 발생합니다. 또한 이것이 더 깨끗한 코드라고 생각합니다.


자, 친구. 두 줄이 필요하고 덜 동적이기 때문에 이것이 최선의 대답인지 완전히 확신하지 못하지만 모두 동일하게 찬성했습니다
Chris McCall

문자열 대신 기호를 사용했기 때문에 덜 역동적이라고 말할 수 있다고 생각합니다. 그러나 코드를 작성할 때 원하는 클래스를 알고 있다면 오타 가능성을 피하기 위해 기호를 사용하는 것이 좋습니다.
Simon Woodside 2011

@sbwoodside : 어떻게 작동 할 수 있습니까? 나는 그것을 시도하고 링커로부터 "Undefined symbols for architecture"를 얻었다.
Lars Schneider

[[[self class] alloc] init]로 변경합니다. 다른 것은 필요하지 않습니다.
Nick Turner

OP의 사용 사례는 합법적입니다. 파일 / 메모리 블록 / plist / 무엇이든간에 개체 계층 구조의 직렬화를위한 기본입니다. 인스턴스화해야 할 클래스를 미리 알지 못하는 경우가 많습니다. 내 사용 사례는 [NSValueTransformer setValueTransformer : MyTransformerA alloc] init] forName : @ "MyTransformerA"]를 복제하는 대신 무량의 "NSValueTransformer"를 "등록"해야하는 지루한 필요성입니다. 40 번-트랜스포머 이름의 NSArray를 스캔하고 문자열에서 생성 / 등록합니다.
Motti Shneor

8

당신이없이 오브젝티브 C로 작업하는 경우 NeXTstep( OS X, iOS, GNUstep등) 시스템 또는 그냥이 방법은 깨끗한 생각, 당신이 활용할 수있는 목표 - 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.