차이점은 무엇이며 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 *
그냥 포인터입니다. 포인터가 가리키는 주소의 내용을 편집 할 수 없습니다.
답변
id
Objective-C 객체에 대한 포인터입니다. 아무것도void *
가리키는 포인터 입니다. 대신에 사용할 수 있지만 컴파일러 경고가 전혀 발생하지 않으므로 권장하지 않습니다.void *
id
stackoverflow.com/questions/466777/whats-the-difference-beclaring-a-variable-id-and-nsobject 및 unixjunkie.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 유형을 설명하는 더 많은 예제가 있습니다 .