[objective-c] Objective-C : id와 void의 차이점 *

차이점은 무엇이며 id그리고 void *?



답변

void * “형식화되지 않은 / 알 수없는 내용의 임의의 청크 메모리에 대한 참조”를 의미합니다.

id “알 수없는 클래스의 임의의 Objective-C 객체에 대한 참조”를 의미합니다.

추가적인 의미 차이가 있습니다.

  • GC Only (GC 전용) 또는 GC Supported (GC 지원) 모드에서 컴파일러는 type 참조가 id아닌 쓰기 장벽 을 생성합니다 void *. 구조를 선언 할 때 이것은 중요한 차이가 될 수 있습니다. iVars를 선언 void *_superPrivateDoNotTouch;하면 _superPrivateDoNotTouch실제로 객체 인 경우 객체를 조기에 수확하게됩니다 . 하지마

  • void *유형 의 참조에서 메소드를 호출하려고 시도 하면 컴파일러 경고가 표시됩니다.

  • id유형 에서 메소드를 호출하려고 시도하면 호출 된 메소드 @interface가 컴파일러가 표시 한 선언에서 선언되지 않은 경우에만 경고합니다 .

따라서 객체를 절대로 참조해서는 안됩니다 void *. 마찬가지로, id타입 변수를 사용하여 객체를 참조 하지 않아야 합니다. 가장 구체적인 클래스 형식의 참조를 사용하십시오. 심지어 NSObject *보다 낫다id 컴파일러는 적어도, 그 기준에 대한 메소드 호출의 더 나은 유효성 검사를 제공 할 수 있기 때문이다.

일반적이고 유효한 용도 중 하나 void *는 다른 API를 통해 전달되는 불투명 한 데이터 참조입니다.

sortedArrayUsingFunction: context:방법을 고려하십시오 NSArray:

- (NSArray *)sortedArrayUsingFunction:(NSInteger (*)(id, id, void *))comparator context:(void *)context;

정렬 함수는 다음과 같이 선언됩니다.

NSInteger mySortFunc(id left, id right, void *context) { ...; }

이 경우 NSArray는 context인수로 전달한 모든 것을 인수로 메소드에 context전달합니다. NSArray에 관한 한 포인터 크기의 데이터가 불투명하고 원하는 목적으로 자유롭게 사용할 수 있습니다.

언어에 클로저 유형 기능이없는 경우, 함수를 사용하여 많은 데이터를 전달할 수있는 유일한 방법입니다. 예; 스레드 안전을 유지하면서 mySortFunc ()가 조건에 따라 대소 문자를 구분하거나 대소 문자를 구분하지 않도록하려면 상황에 따라 대 / 소문자를 구분하는 표시기를 전달합니다.

깨지기 쉽고 오류가 발생하기 쉽지만 유일한 방법입니다.

블록은 이것을 해결합니다-블록은 C의 클로저입니다. Clang에서 사용할 수 있습니다-http: //llvm.org/ 및 Snow Leopard ( http://developer.apple.com/library/ios/documentation/Performance /Reference/GCD_libdispatch_Ref/GCD_libdispatch_Ref.pdf ).


답변

id는 목적 C 객체에 대한 포인터이며, void *는 모든 것에 대한 포인터입니다.

id는 알 수없는 mthod 호출과 관련된 경고도 해제합니다. 예를 들면 다음과 같습니다.

[(id)obj doSomethingWeirdYouveNeverHeardOf];

알 수없는 방법에 대한 일반적인 경고를 제공하지 않습니다. 물론 obj가 nil이거나 실제로 해당 메소드를 구현하지 않는 한 런타임에 예외가 발생합니다.

종종 당신은 사용해야 NSObject*id<NSObject>에 우선 id당신이 안전하게에 / 해제 / 오토 릴리즈를 유지하는 등의 방법을 사용할 수 있도록 적어도 확인한다에 반환되는 객체는, 코코아 객체입니다.


답변

메소드에 리턴 유형이 id있으면 Objective-C 오브젝트를 리턴 할 수 있습니다.

void 즉, 메소드는 아무것도 반환하지 않습니다.

void *그냥 포인터입니다. 포인터가 가리키는 주소의 내용을 편집 할 수 없습니다.


답변

idObjective-C 객체에 대한 포인터입니다. 아무것도void * 가리키는 포인터 입니다. 대신에 사용할 수 있지만 컴파일러 경고가 전혀 발생하지 않으므로 권장하지 않습니다.void *id

stackoverflow.com/questions/466777/whats-the-difference-beclaring-a-variable-id-and-nsobjectunixjunkie.blogspot.com/2008/03/id-vs-nsobject-vs 를 참조하십시오. -id.html .


답변

/// Represents an instance of a class.
struct objc_object {
    Class isa  OBJC_ISA_AVAILABILITY;
};

/// A pointer to an instance of a class.
typedef struct objc_object *id;

위의 코드는 objc.h의 코드이므로 id는 objc_object 구조체의 인스턴스이며 isa 포인터는 Objective C Class 객체와 바인딩 할 수 있지만 void *는 형식화되지 않은 포인터입니다.


답변

내 이해는 id가 객체에 대한 포인터를 나타내는 반면 void *는 사용하려는 유형으로 캐스팅하는 한 실제로 무엇이든 가리킬 수 있다는 것입니다.


답변

이미 말한 것 외에도 컬렉션과 관련된 객체와 포인터 사이에는 차이가 있습니다. 예를 들어, NSArray에 무언가를 넣으려면 “id”유형의 객체가 필요하며 “void *”유형의 원시 데이터 포인터를 사용할 수 없습니다. 컬렉션 내에서 사용하기 위해 “id”형식 [NSValue valueWithPointer:rawData]으로 변환하는 void *rawDdata데 사용할 수 있습니다 . 일반적으로 “id”는 더 유연하며 연결된 객체와 관련된 의미가 더 많습니다. Objective C의 id 유형을 설명하는 더 많은 예제가 있습니다 .