문제

차이점은 무엇입니까? id 그리고 void *?

도움이 되었습니까?

해결책

void * "유형이없는/알 수없는 내용을 가진 임의의 청크 O '메모리에 대한 참조"를 의미합니다.

id "알 수없는 클래스의 임의 대상 C 객체에 대한 언급"을 의미합니다.

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

  • GC 전용 또는 GC 지원 모드에서 컴파일러는 유형의 참조에 대한 쓰기 장벽을 방출합니다. id, 그러나 유형은 아닙니다 void *. 구조를 선언 할 때 이것은 중요한 차이가 될 수 있습니다. Ivars가 좋아하는 선언 void *_superPrivateDoNotTouch; IF가있는 개체를 조기 수확 할 것입니다 _superPrivateDoNotTouch 실제로 대상입니다. 그렇게하지 마십시오.

  • 참조에서 메소드를 호출하려고 시도합니다 void * 유형은 컴파일러 경고를 바꾸게됩니다.

  • An에서 메소드를 호출하려고 시도합니다 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 ()가 조건부로 사례에 민감하거나 사례 무의미한 것으로 정렬되기를 원한다면 여전히 스레드-안전한 경우에도 컨텍스트에서 IS- 사례에 민감한 표시기를 전달하여 출시 중에 캐스팅 될 수 있습니다.

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

블록은 이것을 해결합니다 -블록은 C의 클로저입니다. Clang에서 사용할 수 있습니다. http://llvm.org/ 그리고 스노우 레오파드에서 널리 퍼져 있습니다 (http://developer.apple.com/library/ios/documentation/performance/gcd_libdispatch_ref/gcd_libdispatch_ref.pdf).

다른 팁

ID는 void*가 무엇이든 포인터 인 목표 C 객체에 대한 포인터입니다.

ID는 또한 알 수없는 mthods를 호출하는 것과 관련된 경고를 꺼냅니다.

[(id)obj doSomethingWeirdYouveNeverHeardOf];

알 수없는 방법에 대한 일반적인 경고를 제공하지 않습니다. 물론 OBJ가 NIL이거나 실제로 해당 방법을 구현하지 않는 한 런타임에 예외를 제기 할 것입니다.

종종 당신은 사용해야합니다 NSObject* 또는 id<NSObject> 선호합니다 id, 반환 된 물체가 코코아 객체임을 확인하므로 유지/릴리스/autoreLease와 같은 방법을 안전하게 사용할 수 있습니다.

메소드에 리턴 유형이있는 경우 id 목표 C 객체를 반환 할 수 있습니다.

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

void * 포인터 일뿐입니다. 포인터가 가리키는 주소에서 컨텐츠를 편집 할 수 없습니다.

id 목표 C 객체에 대한 포인터입니다. void * 포인터입니다 아무것. 당신은 사용할 수 있습니다 void * 대신에 id, 그러나, 당신은 아무것도 컴파일러 경고를받지 않기 때문에 권장되지 않습니다.

보고 싶을 수도 있습니다 stackoverflow.com/questions/466777/whats-the-difference-between-declaring-a-variable-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 struct의 인스턴스 인 것처럼 보이며 ISA 포인터는 모든 목적 C 클래스 객체와 바인딩 할 수 있지만 void*는 단지 유형의 포인터입니다.

내 이해는 ID가 객체에 대한 포인터를 나타내는 반면 void *는 실제로 무엇이든 지적 할 수 있다는 것입니다.

이미 말한 것 외에도 컬렉션과 관련된 객체와 포인터 사이에는 차이가 있습니다. 예를 들어, NSARRAY에 무언가를 넣으려면 ( "ID"유형의 객체가 필요하며, 유형의 "void *"의 원시 데이터 포인터를 사용할 수 없습니다. 당신이 사용할 수있는 [NSValue valueWithPointer:rawData] 변환하다 void *rawDdata 컬렉션 내부에서 사용하기위한 "ID"유형으로. 일반적으로 "ID"는 더 유연하며 첨부 된 물체와 관련된 의미론이 더 많습니다. 설명하는 더 많은 예가 있습니다 ID 유형의 목표 c는 여기에 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top