Objective-C의 문법 설탕 @{} 도대체 무엇인지 상세히 설명합니다.
5579 단어 objective-c문법 설탕@{}
NSMutableDictionary *mDic1 = [NSMutableDictionary dictionaryWithDictionary:@{@"a":@1, @"a":@2}];
//'a': 1
NSMutableDictionary *mDic2 = [NSMutableDictionary dictionary];
[mDic2 setObject:@(1) forKey:@"a"];
[mDic2 setObject:@(2) forKey:@"a"];
//'a': 2
이에 대해 필자는 약간의 연구를 하였는데, 여기에서 나는 이유를 논술하고 실험 절차를 약술하였다@{} 도대체 뭐예요?
이 데이터의 결과를 초래할 가능성 중 하나는
@{@"a":@1, @"a":@2}
그 자체가 키가 a이고 값이 1인 사전이다.테스트 코드는 다음과 같습니다.
NSDictionary *dic = @{@"a":@1, @"a":@2};
NSLog(@"%@", dic);
그 자체가 키가 a이고 값이 1인 사전이라는 것을 발견했다.그럼 @{}는 도대체 무엇일까요?사실 어떻게 조작했죠?그의 분배 방식은 도대체 무엇입니까?
실험 절차
인터넷에서 찾은 NSDictionary의 위조 코드를 기반으로 하여, 어쨌든 우리가 사전을 만들 때, 그 코드는 최종적으로 실행될 것이다
- (id)initWithObjects:(const id [])objects forKeys:(const id <NSCopying> [])keys count:(NSUInteger)cnt
그러면 만약에 우리가 훅을 통해 이 방법을 감청한다면 초기화할 때 전송된objects와keys가 도대체 무엇인지 알 수 있습니다.하지만 안타깝게도 훅이 살지 않았다.설마 내 방법에 문제가 있는 건 아니겠지?
필자는 @{}를 사용할 때 이 절차를 전혀 실행하지 않는 것을 발견했다.다른 건가요?
그리고 필자는 기호 단점
+[NSDictionary dictionaryWithObjects:forKeys:count:]
을 추가함으로써 우리가 값을 부여할 때 기호 단점이 연결된다는 것을 발견했다.우리는 @{} 사전을 만들 때 이 방법을 사용합니까?해볼만해?
hook을 통해 사전의 이 방법을 사용했습니다. 우리는 분류에서 받아들일 것입니다. 시스템이 호출될 때 단점을 걸어 둡니다.
+ (id)xxx_dictionaryWithObjects:(const id [])objects forKeys:(const id <NSCopying> [])keys count:(NSUInteger)cnt{
for (NSUInteger i = 0; i < cnt; i++) {
id key = keys[i];
id obj = objects[i];
NSLog(@"key = %@", key);
NSLog(@"obj = %@", obj);
}
return [[NSDictionary class] xxx_dictionaryWithObjects:objects forKeys:keys count:cnt];
}
2021-03-30 17:13:40.971674+0800 suspenseRoad[28886:413231] key = a2021-03-30 17:13:40.971743+0800 suspenseRoad[28886:413231] obj = 1
2021-03-30 17:13:40.971814+0800 suspenseRoad[28886:413231] key = a
2021-03-30 17:13:40.971896+0800 suspenseRoad[28886:413231] obj = 2
다음 결과를 기다립니다. 설정을 초기화할 때 전송된 값은 코드에 들어갔지만 결과는 없습니다.
계속 탐구하는 방법
+[NSDictionary dictionaryWithObjects:forKeys:count:]
+ (id)dictionaryWithDictionary:(NSDictionary *)dict
{
size_t count = [dict count];
id *objects = NULL;
id *keys = NULL;
if (count > 0) {
objects = malloc(sizeof(id) * count);
if (UNLIKELY(objects == NULL)) {
return NULL;
}
keys = malloc(sizeof(id) * count);
if (UNLIKELY(keys == NULL)) {
free(objects);
return NULL;
}
}
[dict getObjects:objects andKeys:keys];
id obj = [[self alloc] initWithObjects:objects forKeys:keys count:count];
if (objects != NULL) {
free(objects);
}
if (keys != NULL) {
free(keys);
}
return [obj autorelease];
}
추측
이때 데이터를 바꿀 수 있는 곳은 두 곳뿐이다.
[dict getObjects:objects andKeys:keys];
//
id obj = [[self alloc] initWithObjects:objects forKeys:keys count:count];
상술한 두 가지 문제 때문에 필자는 모두 단도할 방법이 없다. 만약에 독자가 큰 방법이 있다면 독자가 크게 시도하기를 바란다.필자는 두 가지 방법의 코드에 근거하여 자신의 대담한 추측을 진행하였다. 즉, 멋대로 추측한 것이다.안타깝게도 고치지 못했다.코드에서objects와keys에 대한 선택을 반복할 수 있는 어떤 방법도 보지 못했다.
CFBasicHashAddValue 및 CFBasicHashSetValue
초기화 방법의 문제가 아닌 것 같다. 그리고 필자는 사전의 set Object:forKey의 실현을 비교했다.다음과 같은 두 가지 방법을 찾습니다.
CF_PRIVATE Boolean CFBasicHashAddValue(CFBasicHashRef ht, uintptr_t stack_key, uintptr_t stack_value) {
・・・
CFBasicHashBucket bkt = __CFBasicHashFindBucket(ht, stack_key);
if (0 < bkt.count) {
ht->bits.mutations++;
if (ht->bits.counts_offset && bkt.count < LONG_MAX) { // if not yet as large as a CFIndex can be... otherwise clamp and do nothing
__CFBasicHashIncSlotCount(ht, bkt.idx);
return true;
}
} else {
__CFBasicHashAddValue(ht, bkt.idx, stack_key, stack_value);
return true;
}
return false;
}
CF_PRIVATE void CFBasicHashSetValue(CFBasicHashRef ht, uintptr_t stack_key, uintptr_t stack_value) {
・・・
CFBasicHashBucket bkt = __CFBasicHashFindBucket(ht, stack_key);
if (0 < bkt.count) {
__CFBasicHashReplaceValue(ht, bkt.idx, stack_key, stack_value);
} else {
__CFBasicHashAddValue(ht, bkt.idx, stack_key, stack_value);
}
}
승리가 멀지 않은 것 같아, 왜냐하면__CFBasicHashReplaceValue는 의미상 대체입니다.그러면 그 본질은 바로 CFBasicHashAddValue이다. 같은 값의 키가 존재할 때 다시 가입하지 않고 최종 결과는 앞의 값으로 설정하는 것이지 뒤의 값으로 설정하는 것이 아니다.마찬가지로 당신도 아래의 값을 얻을 수 있습니다. 답을 평론 구역에 쓰는 것을 환영합니다.
[NSDictionary dictionaryWithObjects:@[@1,@2,@3,@4,@5,@6,@7,@8,@9,@0] forKeys:@[@"a",@"b", @"a", @"b", @"a", @"a", @"b", @"b", @"a", @"b"]]
기타
hook 사전 자체의dictionary With Objects:for Keys:count: 시스템의 상태 표시줄에 국한되지 않는 정보를 포함하여 최종적으로 하나의 사전에 저장해야 합니다. 그 저장 시기는 프로젝트가 실행될 때입니다. NSDictionary *dic = @{@'a': @1, @'a': @2};이전에 인터럽트를 걸고 dictionary With Objects: for Keys:count: 인터럽트를 놓습니다.
Objective-C의 문법당 @{}가 무엇인지에 관한 이 글은 여기까지 소개합니다. 더 많은 Objective-C 문법당 @{} 내용은 저희 이전의 글을 검색하거나 아래의 관련 글을 계속 훑어보십시오. 앞으로 많은 응원 부탁드립니다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
iOS 메모설 연휴 동안 회사의 프로젝트 시간이 매우 바쁜 데다가 자신이 iOS의 작은 프로젝트를 하나 하고 있기 때문에 퇴근과 주말 시간에 거의 쉬지 않아서 블로그도 태만해졌다. 여기에는 내가 이 작은 프로젝트를 쓸 때 사용...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.