목표-C: id와 void의 차이 *
사이의 차이점은 무엇입니까?id
그리고.void *
?
void *
"입력되지 않은/잘못된 내용이 있는 일부 랜덤 청크 메모리에 대한 참조"를 의미합니다.
id
"알 수 없는 클래스의 임의의 Objective-C 객체에 대한 참조"를 의미합니다.
추가적인 의미론적 차이가 있습니다.
GC Only 또는 GC Supported 모드에서 컴파일러는 유형 참조에 대한 쓰기 장벽을 방출합니다.
id
하지만 유형은 아닙니다.void *
구조를 선언할 때 중요한 차이가 될 수 있습니다.iVars like 선언void *_superPrivateDoNotTouch;
다음과 같은 경우 조기에 물건을 수확할 수 있습니다._superPrivateDoNotTouch
실제로는 물체입니다.그러지마세요.다음을 참조하여 메서드 호출 시도
void *
type은 컴파일러 경고를 표시합니다.에서 메서드 호출 시도
id
type은 호출 중인 메서드가 다음 중 하나에서 선언되지 않은 경우에만 경고합니다.@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) { ...; }
이 경우, NSA ray는 당신이 통과하는 모든 것을 전달할 뿐입니다.context
을 통한 방법에 대한 주장.context
논쟁.NSArray에 관한 한 포인터 크기의 불투명한 데이터 덩어리이며, 원하는 용도로 자유롭게 사용할 수 있습니다.
언어에 폐쇄 유형 기능이 없으면 함수가 있는 데이터 덩어리를 가지고 다닐 수 있는 유일한 방법입니다.예를 들어, mySortFunc()가 조건부로 대/소문자를 구분하거나 대/소문자를 구분하지 않고 정렬하는 동시에 스레드에 안전한 상태를 유지하려면 상황에 따라 is-대/소문자를 구분하는 표시기를 전달하여 들어오고 나가는 경로를 결정할 수 있습니다.
취약하고 오류가 발생하기 쉽지만 유일한 방법입니다.
블록은 이 문제를 해결합니다. 블록은 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는 또한 알 수 없는 메서드 호출과 관련된 경고를 해제합니다. 예를 들어 다음과 같습니다.
[(id)obj doSomethingWeirdYouveNeverHeardOf];
에서는 알 수 없는 메서드에 대한 일반적인 경고를 제공하지 않습니다.물론 obj가 0이거나 실제로 그 방법을 구현하지 않는 한 런타임에 예외가 발생합니다.
은 종종 자주사야합니다해를 해야 합니다.NSObject*
또는id<NSObject>
id
최소한 반환된 개체가 코코아 개체임을 확인하기 때문에 이 개체에 대해 보존/해제/자동 해제와 같은 방법을 안전하게 사용할 수 있습니다.
이 메드의반유다같경은우인 id
Objective-C 객체를 반환할 수 있습니다.
void
메소드가 아무것도 반환하지 않는다는 의미입니다.
void *
포인터일 뿐입니다.포인터가 가리키는 주소의 내용을 편집할 수 없습니다.
id
Objective-C 개체에 대한 포인터입니다. void *
모든 항목에 대한 포인터입니다.사용할 수 있습니다.void *
에 id
그러나 컴파일러 경고가 표시되지 않기 때문에 권장되지 않습니다.
stackoverflow.com/questions/466777/whats-the-difference-between-declaring-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 구조체의 인스턴스이며 포인터는 임의의 Object C 클래스 개체와 바인딩할 수 있는 반면 void*는 입력되지 않은 포인터에 불과합니다.
제가 이해하는 바로는 id는 객체에 대한 포인터를 나타내는 반면 void *는 실제로 무엇이든 가리킬 수 있습니다. 그런 다음 사용할 유형으로 캐스팅하기만 하면 됩니다.
이미 말한 것 외에도 컬렉션과 관련된 객체와 포인터 사이에는 차이가 있습니다.예를 들어, NSA ray에 무언가를 넣으려면 개체("id" 유형)가 필요하며, 여기서 원시 데이터 포인터("void *" 유형)를 사용할 수 없습니다.사용할 수 있습니다.[NSValue valueWithPointer:rawData]
변환하다void *rawDdata
컬렉션 내에서 사용하기 위해 "id" 유형으로 변경합니다.일반적으로 "id"는 더 유연하고 연결된 개체와 관련된 더 많은 의미를 가집니다.여기에는 목표 C의 ID 유형을 설명하는 더 많은 예가 있습니다.
언급URL : https://stackoverflow.com/questions/1304176/objective-c-difference-between-id-and-void
'programing' 카테고리의 다른 글
ASP에 필요한 확인란을 만들려면 어떻게 해야 합니까?NET 양식? (0) | 2023.05.06 |
---|---|
Meteor가 실행되는 동안 다른 클라이언트에서 Meteor의 MongoDB에 액세스하려면 어떻게 해야 합니까? (0) | 2023.05.06 |
Windows용 ActivePerl 또는 StrawberryPerl 중 어느 것을 선택해야 합니까? (0) | 2023.05.06 |
PHP 스프레드시트로 매우 큰 스프레드시트 구축 (0) | 2023.05.06 |
고유 사용자 ID의 시퀀스를 저장하기 위한 MongoDB의 자동 증분 (0) | 2023.05.06 |