Это второстепенный вопрос, который возник из сообщения, которое я сделал сегодня сегодня. У меня есть метод ниже, который отлично работает для того, что мне нужно, но иногда сбой, когда я вызываю CFRelease
в переменной hostRef
. Я думаю, что это может быть связано с ресурсом, который используется в другом месте, когда я пытаюсь его выпустить, но насколько я могу судить, я синхронно разрешаю хост, и я не получаю доступ к нему из другого потока.Вызов CFRelease для CFHostRef иногда будет сбой
Я попытался позвонить CFHostCancelInfoResolution
до CFRelease
, но это не изменило частоту сбоев. Я думал, что отправлю это здесь, чтобы узнать, есть ли какие-то предположения или неправильные представления, которые у меня есть, которые не соответствуют действительности.
+ (NSArray *) addressesForHostname: (NSString *)hostname {
CFMutableArrayRef ipAddresses = nil;
DLog(@"Getting addresses for host name %@", hostname);
CFHostRef hostRef = CFHostCreateWithName(kCFAllocatorDefault, (__bridge CFStringRef)(hostname));
CFStreamError error;
BOOL didResolve = CFHostStartInfoResolution(hostRef, kCFHostAddresses, &error); // synchronously get the host.
if (didResolve) {
CFArrayRef responseObjects = CFHostGetAddressing(hostRef, NULL);
long numberOfResponses = CFArrayGetCount(responseObjects);
ipAddresses = CFArrayCreateMutable(kCFAllocatorDefault, numberOfResponses, &kCFTypeArrayCallBacks);
for (int i = 0 ; i < numberOfResponses; ++i) {
char * ipAddress = NULL;
CFDataRef responseObject = CFArrayGetValueAtIndex(responseObjects, i);
struct sockaddr * currentAddress = (struct sockaddr *) CFDataGetBytePtr(responseObject); // Unwrap the CFData wrapper aound the sockaddr struct
switch (currentAddress->sa_family) {
case AF_INET: { // Internetworking AKA IPV4
DLog(@"Extracting IPV4 address");
struct sockaddr_in * socketAddress = (struct sockaddr_in *) currentAddress;
ipAddress = malloc(sizeof(INET_ADDRSTRLEN));
inet_ntop(AF_INET,
&(socketAddress->sin_addr),
ipAddress,
INET_ADDRSTRLEN);
CFStringRef ipAddressString = CFStringCreateWithCString(kCFAllocatorDefault, ipAddress, kCFStringEncodingASCII);
CFArrayInsertValueAtIndex(ipAddresses, i, ipAddressString);
break;
}
case AF_INET6: { // IPV6
DLog(@"Extracting IPV6 address");
struct sockaddr_in6 * socketAddress = (struct sockaddr_in6 *) currentAddress;
ipAddress = malloc(sizeof(INET6_ADDRSTRLEN));
inet_ntop(AF_INET6,
&(socketAddress->sin6_addr),
ipAddress,
INET6_ADDRSTRLEN);
CFStringRef ipAddressString = CFStringCreateWithCString(kCFAllocatorDefault, ipAddress, kCFStringEncodingASCII);
CFArrayInsertValueAtIndex(ipAddresses, i, ipAddressString);
break;
}
default:
DLog(@"Unsupported addressing protocol encountered. Gracefully ignoring and continuing.");
break;
}
if(ipAddress != NULL) {
free(ipAddress);
}
}
CFRelease(responseObjects);
}
CFRelease(hostRef);
return (__bridge_transfer NSArray *) ipAddresses;
}
Причина заключается в соглашениях об именах CoreFoundation. Он описан в документе [Руководство по программированию памяти для Core Foundation] (https://developer.apple.com/library/mac/documentation/CoreFoundation/Conceptual/CFMemoryMgmt/Concepts/Ownership.html). – JustSid