디버거에서 NSZombieEnabled, MallocStackLogging 및 guard malloc을 설정하십시오.
(gdb) info malloc-history 0x543216
가 충돌의 원인이 된 객체의 주소 0x543216 교체, 당신은 훨씬 더 유용한 스택 추적을 얻을 것이다 그것을 당신이 정확하게 도움이 될 것입니다 그런 다음 응용 프로그램이 충돌 할 때, gdb를 콘솔에서이 입력 문제를 일으키는 코드의 정확한 줄
- 더 생각 -
self.allKeys
실제로
이 "모든 속성의 배열 (문자열로 각 속성)"다음
당신은 아마 가야 ABPropertyID
은이므로 배열 객체 (속성)의 . 같은 뭔가 :
currentFieldProperty = (ABPropertyID)[[self.allKeys objectAtIndex:j] intValue];
ABRecordCopyValue(currentRecordRef, currentFieldProperty)
그러나 우리는 self.allKeys
의 값을 참조하거나이 확실하게 채워집니다 어떻게해야합니다.
ABRecordCopyValue
ABRecordRef Reference에서
및 CFTypeRef Reference-는 기록 프로퍼티의 값을 돌려줍니다.
CFTypeRef ABRecordCopyValue (
ABRecordRef record,
ABPropertyID property
);
매개 변수
record
-문제의 속성을 포함하는 기록.
property
- 값이 반환되는 레코드의 속성입니다. 레코드 재산의
반환 값
값.
그리고 :
ABPropertyID
- 기록 속성을 식별 정수.
typedef int32_t ABPropertyID;
- 그리고 자세한 문제 해결 아이디어 - 당신이 (NSString*)ABRecordCopyValue(currentRecordRef, currentFieldProperty)
에 NSString *
에 CFTypeRef
캐스팅 할 때
(가) 위의 경우가 아닌 경우는, 다음 충돌은 그래서 여기입니다 발생할 수 있습니다 그걸 해결할 수있는 작은 도우미 기능 :
- (NSString*)stringValueForCFType:(CFTypeRef)cfValue {
NSString *stringValue = nil;
if (!cfValue) return nil;
CFTypeID cfType = CFGetTypeID(cfValue);
if (cfType == CFStringGetTypeID()) {
stringValue = [[(id)CFMakeCollectable(cfValue) retain] autorelease];
} else if (cfType == CFURLGetTypeID()) {
stringValue = [(NSURL*)cfValue absoluteString];
} else if (cfType == CFNumberGetTypeID()) {
stringValue = [(NSNumber*)cfValue stringValue];
} else if (cfType == CFNullGetTypeID()) {
stringValue = [NSString string];
} else if (cfType == AXUIElementGetTypeID()) {
stringValue = [[GTMAXUIElement elementWithElement:cfValue] description];
} else if (cfType == AXValueGetTypeID()) {
stringValue = [self stringValueForAXValue:cfValue];
} else if (cfType == CFArrayGetTypeID()) {
stringValue = [self stringValueForCFArray:cfValue];
} else if (cfType == CFBooleanGetTypeID()) {
stringValue = CFBooleanGetValue(cfValue) ? @"YES" : @"NO";
} else {
CFStringRef description = CFCopyDescription(cfValue);
stringValue = [(id)CFMakeCollectable(description) autorelease];
}
return stringValue;
}
다음 currentRecord = [self stringValueForCFType:ABRecordCopyValue(currentRecordRef, currentFieldProperty)];
을하고 self.allKeys
인덱스 j
에서 개체가 있는지 확인하십시오 및 self.allContacts
인덱스 i
에서 객체가 있습니다
NSString *currentRecord = [[NSString alloc] init];
ABRecordRef currentRecordRef;
ABPropertyID currentFieldProperty;
if (self.allContacts.count > i) {
currentRecordRef = (ABRecordRef)[self.allContacts objectAtIndex:i];
if (self.allKeys.count > j) {
currentFieldProperty = (ABPropertyID)[self.allKeys objectAtIndex:j];
currentRecord = [self stringValueForCFType:ABRecordCopyValue(currentRecordRef, currentFieldProperty)];
} else {
NSLog(@"self.allKeys has no value at index (%d): %@", j, [allKeys description]);
}
} else {
NSLog(@"self.allContacts has no value at index (%d): %@", i, [allContacts description]);
}
(코멘트에 대한)
편집 :
가의 문자열을 변환하려면 속성 이름을 int 값으로 변경하려면 다음을 작성해야합니다 (올바른 순서가 아니어야하므로 NSLog
먼저 순서가 무엇인지 확인하십시오.)
(210)
NSString * const ABPropertyID_toString[] = {
@"kABPersonFirstNameProperty",
@"kABPersonLastNameProperty",
@"kABPersonMiddleNameProperty",
@"kABPersonPrefixProperty",
@"kABPersonSuffixProperty",
@"kABPersonNicknameProperty",
@"kABPersonFirstNamePhoneticProperty",
@"kABPersonLastNamePhoneticProperty",
@"kABPersonMiddleNamePhoneticProperty",
@"kABPersonOrganizationProperty",
@"kABPersonJobTitleProperty",
@"kABPersonDepartmentProperty",
@"kABPersonEmailProperty",
@"kABPersonBirthdayProperty",
@"kABPersonNoteProperty",
@"kABPersonCreationDateProperty",
@"kABPersonModificationDateProperty",
@"kABPersonAddressProperty",
// ... etc
};
- (NSString *)ABPropertyIDToString:(ABPropertyID)propertyVal {
return ABPropertyID_toString[propertyVal];
}
- (ABPropertyID)stringToABPropertyID:(NSString *)propertyString {
int retVal;
for(int i=0; i < sizeof(ABPropertyID_toString) - 1; ++i) {
if([(NSString *)ABPropertyID_toString[i] isEqual:propertyString]) {
retVal = i;
break;
}
}
return retVal;
}
그런 다음 배열 [self.allKeys objectAtIndex:j]
에서 stringToABPropertyID:
값을 전달하고 반환 할 것 ABPropertyID
:
currentFieldProperty = [self stringToABPropertyID:[self.allKeys objectAtIndex:j]];
self.allKeys가 채워지는 방법을 언급하지 않았습니다. 또한, 충돌시 얻을 수있는 유용한 정보가 있습니까? – Stavash
self.allKeys는 kABPersonFirstNameProperty와 같은 모든 ABPropertyID 속성을 보유하는 배열입니다. 충돌시 로그를 수신하지 않습니다. –
ABRecordCopyValue가 충돌을 일으킨다는 것을 어떻게 알 수 있습니까? EXC_BAD_ACCESS를 받으십니까? SIGBRT? 그 문제에 대해 어떤 생각을 밝힐만한 것이 있습니까? – Stavash