2011-10-24 6 views

답변

16

왜 약한 참조 포인터입니까?

id은 적어도 ARC 소유권이 아닌 약한 참조 포인터가 아닙니다. id 객체에 대한 형식화 된 참조가 약한 지 여부는 __weak (및 변형)으로 선언 된 참조 및 실제로 약한 참조를 지원하는 객체의 클래스에 따라 다릅니다.

그러나 id약식 타이핑을 제공한다고 말할 수 있지만 동적/오리 타이핑이 더 정확한 설명이라고 생각할 수 있습니다. id 유형 참조에는 컴파일 타임 클래스 유형 정보가 없기 때문에 컴파일러는 기본 객체가 지정된 선택자에 응답 할 수 있는지 여부를 결정할 수 없으므로 런타임 오류가 발생할 수 있습니다.

어떤 클래스 유형의 포인터도 어떻게 처리 할 수 ​​있습니까?

이는 정의의 일부인 the Objective-C language입니다. 컴파일러는 id을 모든 Objective-C 클래스의 수퍼 유형으로 인식하고 id을 다르게 처리합니다. 아래 답변도 참조하십시오.

런타임시 어떤 유형의 클래스 포인터가 id에 할당되었는지 감지 할 수 있습니까?

는 애플의 목표 - C 런타임에서 객체에 할당 된 메모리의 첫 번째 바이트는 그 객체의 클래스를 가리켜 야합니다. 다른 곳에서 참조 된 것을 isa 포인터로 볼 수 있습니다. Apple의 런타임이 개체의 클래스를 찾는 방식입니다. id 유형은이 정보도 포함하도록 정의됩니다. 사실 유일한 속성은 isa 포인터입니다. 이는 Objective-C 객체가이 정의를 따르는 것을 의미합니다. 당신이 id 참조를 가지고 참조 된 개체의 클래스를 발견 할 경우

, 당신은 그것을 -class을 보낼 수 있습니다

id someObject; 

// Assign something to someObject 

// Log the corresponding class 
Class c = [someObject class]; 
NSLog(@"class = %@", c); 

// Test whether the object is of type NSString (or a subclass of NSString) 
if ([someObject isKindOfClass:[NSString class]]) { 
    NSLog(@"it's a string"); 
} 

1Tagged pointers이 구조의 주목할만한 편차, 그리고 (부분적으로) 그들 때문에 포인터는 isa에 직접 액세스하면 안됩니다.

7

일반 개체 형식을 사용하는 것이 좋으므로 모든 종류의 개체를 보유 할 수있는 컬렉션 형식과 어떤 종류의 개체인지 모르게 개체에서 작동하는 다른 일반 서비스를 정의 할 수 있습니다.

ID를 작동시키는 트릭이 없습니다. 2 진 레벨에서 모든 포인터는 상호 교환 가능합니다. 그들은 메모리 주소를 숫자 값으로 나타냅니다. id가 어떤 유형의 포인터라도 받아 들일 수있게하려면 은 대개 포인터 유형이 일치해야하는 컴파일러의 규칙 만 비활성화하면됩니다.

id theObject = // ... something 
Class theClass = [theObject class]; 
NSString *className = NSStringFromClass(theClass); 
NSClassDescription *classDescription = [NSClassDescription classDescriptionForClass:theClass]; 

을하지만 코드에서 물건 이러한 종류의 작업을 수행 할 필요는 거의 없습니다 :

여러 가지 방법의 이러한 종류의 ID 유형 변수의 클래스에 대한 정보를 확인할 수 있습니다. 더 자주, 당신은 id 변수가 특정 클래스의 인스턴스인지 테스트하고, 그렇다면 그 클래스에 캐스트하고 그 타입으로 취급하기 시작합니다.

if ([theObject isKindOfClass:[MySpecializedClass class]]) { 
    MySpecializedClass *specialObject = (MySpecializedClass *)theObject; 
    [specialObject doSomethingSpecial]; 
} 

것은 당신이 클래스를 찾을 -class를 사용했다,하지만 당신에 대해 아무것도 몰라 클래스를 반환하는 경우, 당신은 어쨌든 그 클래스를 기반으로 객체로 할 수있는 특별한 것은 없다. 그래서 아무 것도 할 이유가 없지만, 여러분이 알고있는 클래스와 일치하는지 그리고 어쨌든 클래스에 대한 특별한 처리를하고자하는 경우에만 확인하십시오.

가끔 isKindOfClass 대신 isMemberOfClass을 사용할 수 있습니다. 정확히 일치하는지 또는 하위 클래스를 포함할지 여부에 따라 다릅니다.

3

id의 내부 정보를 찾으려면 objc/objc.h 헤더 파일을 살펴 보는 것이 좋습니다.

typedef struct objc_class *Class; 
typedef struct objc_object { 
    Class isa; 
} *id; 


typedef struct objc_selector *SEL;  
typedef id   (*IMP)(id, SEL, ...); 
관련 문제