OC runtime 학습 노트 관련 대상
Objective-C 는 대상 에 속성 을 동적 으로 추가 할 수 없습니다.다른 원생 들 이 지원 하 는 언어 와 다 릅 니 다.그래서 앞으로 늘 어 날 변 수 를 위해 공간 을 마련 하려 고 노력 해 야 했다.맥 OS X 10.6 에서 오 브 젝 티 브-C 의 런 타임 은 이미 이 기능 을 원생 으로 지원 했다.
OC runtime 에서 관련 대상 의 방법 은 모두 가 사용 한 적 이 있다 고 믿 지만 그 원리 와 내부 실현 은 많은 사람들 이 모른다.이 글 은 OC runtime 의 관련 대상 을 설명 하고 바로 본론 으로 들 어 갑 니 다.
runtime 관련 대상 원리
runtime 에서 제공 하 는 API 는 다음 과 같 습 니 다.
///
typedef OBJC_ENUM(uintptr_t, objc_AssociationPolicy) {
OBJC_ASSOCIATION_ASSIGN = 0, /**< */
OBJC_ASSOCIATION_RETAIN_NONATOMIC = 1, /**< . . */
OBJC_ASSOCIATION_COPY_NONATOMIC = 3, /**< . . */
OBJC_ASSOCIATION_RETAIN = 01401, /**< . . */
OBJC_ASSOCIATION_COPY = 01403 /**< . . */
};
/**
* key policy object
*/
void objc_setAssociatedObject(id object, const void * key, id value, objc_AssociationPolicy policy);
/**
* object key
*/
id objc_getAssociatedObject(id object, const void * key);
/**
* object
*/
void objc_removeAssociatedObjects(id object);
runtime 의 API 는 매우 간단 합 니 다.실제로 작업 중 runtime 의 관련 대상 을 사용 하 는 것 도 편리 합 니 다.다음 과 같 습 니 다.
static const void * _Nonnull titleKey = @"titleKey";
- (void)setTitle:(NSString *)title
{
objc_setAssociatedObject(self, titleKey, key, OBJC_ASSOCIATION_RETAIN);
}
- (NSString *)title
{
return objc_getAssociatedObject(self, titleKey);
}
이렇게 간단 하고 강력 한 기능 은 시스템 의 실현 을 관찰 하려 면 관련 대상 의 소스 코드 를 찾 을 수 있 습 니 다.우 리 는 obsc 소스 코드 에서 얻 을 수 있 습 니 다.원본 코드 에서 상기 세 개의 API 의 실현 은 다음 과 같다.
obbc 로setAssociated Object 방법 을 예 로 들 면 방법 내부 에서 호출 된 내부 방법 은 매개 변수 가 같 고 내부 로 들 어 가 는 방법 이다
/// 。
void _object_set_associative_reference(id object, void *key, id value, uintptr_t policy) {
// ,
ObjcAssociation old_association(0, nil);
//
id new_value = value ? acquireValue(value, policy) : nil;
{
// . AssociationsHashMap
AssociationsManager manager;
// Map
AssociationsHashMap &associations(manager.associations());
// 。 object
disguised_ptr_t disguised_object = DISGUISE(object);
if (new_value) {
//
AssociationsHashMap::iterator i = associations.find(disguised_object); // key AssociationsHashMap objc Map
if (i != associations.end()) {
// Map 。 map: ObjectAssociationMap
ObjectAssociationMap *refs = i->second;
// ObjectAssociationMap
ObjectAssociationMap::iterator j = refs->find(key); // key ObjectAssociationMap ObjcAssociation
if (j != refs->end()) {
// ObjcAssociation , old_association
old_association = j->second;
j->second = ObjcAssociation(policy, new_value);
} else {
// ->
(*refs)[key] = ObjcAssociation(policy, new_value);
}
} else {
// Map
ObjectAssociationMap *refs = new ObjectAssociationMap;
associations[disguised_object] = refs;
(*refs)[key] = ObjcAssociation(policy, new_value);
object->setHasAssociatedObjects();
}
} else {
// value , nil。
AssociationsHashMap::iterator i = associations.find(disguised_object);
if (i != associations.end()) {
ObjectAssociationMap *refs = i->second;
ObjectAssociationMap::iterator j = refs->find(key);
if (j != refs->end()) {
old_association = j->second;
refs->erase(j);
}
}
}
}
// old value.
if (old_association.hasValue()) ReleaseValue()(old_association);
}
원본 코드 에서 볼 수 있 듯 이 유지보수 대상 과 관련 된 대상 은 주로 네 개 입 니 다.AssociationsManager // 관련 관 계 를 유지 하 는 전역 관리자--->Associations HashMap 저장
AssociationsHashMap // 관련 관 계 를 저장 하 는 HashMap--->대상 에 대응 하 는 관련 관 계 를 저장 하 는 Map
Object Association Map//대상 관련 관계 맵,2 급 맵
ObjcAssociation // 연관 관계
그들의 관 계 는 그림 으로 다음 과 같이 표시 합 니 다.
runtime
우리 의 대상 외부 에서 대상 관련 체 제 를 재 구축 하고 관리 하 며 이중 hashMap 을 통 해 대상 간 의 관련 관 계 를 유지 하 는 것 과 같다.그 중에서 Associations HashMap(외층 Map)은 Associations Manager 에 저 장 된 전역 정적 맵 입 니 다.대상 의 메모리 주소 처 리 를 통 해 대상 과 유일 하 게 연 결 된 key 를 map 에 저장 하고 대상 과 관련 된 Object Association Map 을 저장 합 니 다.이 map 는 Objc Association(관련 정책 과 값)을 유지 합 니 다.
이상 obj csetAssociated Object 를 예 로 들 어 관련 대상 의 원 리 를 설명 하 였 습 니 다.obbcgetAssociated Object 와 obbcremove Associated Objects 원리 도 마찬가지다.
사유 확장
runtime 에서 대상 과 관련 된 원 리 는 위 와 같이 애플 소스 코드 의 사상 을 배 웠 다.업무 중 에 비슷 한 데이터 저장 이 마침 참고 할 수 있다 는 것 을 알 수 있다.
마침 오후 에 runtime 대상 의 관련 원 리 를 연구 할 때 친구 가 나 에 게 다 중 사용자 시스템 의 실현 논 리 를 물 었 다.
대 의 는:
4.567917.사용 자 는 핸드폰 번호 로 로그 인 한 후에 메모리 에 사용자 정보 표를 생 성 합 니 다.표 에 사용자 의 예 를 들 어 개인 기본 정보,연락처 정보,지갑 정 보 를 저장 할 수 있 습 니 다.4.567918.
사용자 로그 인 id 를 통 해 key 에 사용자 정보 맵 을 만 듭 니 다.모든 사용자 id 가 유일한 사용자 정보 표 에 대응 하 는 지 확인 하고 사용자 정보 표 에 어떤 정 보 를 저장 하고 싶 은 지 사용자 정의 합 니 다.
총결산
이상 은 이 글 의 전체 내용 입 니 다.본 논문 의 내용 이 여러분 의 학습 이나 업무 에 어느 정도 참고 학습 가치 가 있 기 를 바 랍 니 다.궁금 한 점 이 있 으 시 면 댓 글 을 남 겨 주 셔 서 저희 에 대한 지지 에 감 사 드 립 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
깊이 복사(mutable Copy)와 얕은 복사(copy) 설명인용 대상의 계수는 1입니다.copy 속성은 두 대상의 내용이 같고 새로운 대상retain은 1이며 기존 대상의 인용 계수와 상관없이 기존 대상은 변하지 않습니다.copy는 상하문에 대한 대상의 의존을 감소합니다. ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.