【发布时间】:2015-06-16 16:28:43
【问题描述】:
我注意到我目前正在编写的代码的行为有些奇怪,我想我会在这里询问我是否在做一些愚蠢的事情会导致这种情况发生。
基本上,当我将一个变量分配给我的类方法的返回值时,不是变量持有对返回值的引用,而是持有对类的引用。请看下面的代码:
NSArray * newAddresses = [MyHost addressesForHostname: @"google.com"];
方法签名为
+ (NSArray *) addressesForHostname: (NSString *)hostname
然后返回
return (__bridge_transfer NSArray *) ipAddresses; // ipAddresses is a CFMutableArrayRef
如您所见,我正在使用免费桥接来使用 CoreFoundation 对象,因为我正在收集一些网络接口的 IP 地址列表。
newAddresses被赋值后,查看LLDB中newAddresses数组的类,得到:
(lldb) po [新地址类]
我的主机
我对如何使用__bridge_transfer 的假设有误吗?构成ipAddresses的所有对象都是CFStringRefs。
编辑:我被要求提供整个方法,所以就在这里!
+ (NSArray *) addressesForHostname: (NSString *)hostname {
CFMutableArrayRef ipAddresses;
DLog(@"Getting addresses for host name %@", hostname);
CFHostRef hostRef = CFHostCreateWithName(kCFAllocatorDefault, (__bridge CFStringRef)(hostname));
CFStreamError error;
BOOL didResolve = CFHostStartInfoResolution(hostRef, kCFHostNames, &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;
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);
free(ipAddress);
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);
free(ipAddress);
break;
}
default:
DLog(@"Unsupported addressing protocol encountered. Gracefully ignoring and continuing.");
break;
}
}
CFRelease(responseObjects);
}
CFRelease(hostRef);
return (__bridge_transfer NSArray *) ipAddresses;
}
【问题讨论】:
-
您能否在方法中显示
ipAddresses的声明,或者更好的是,发布整个方法?看起来它实际上不是一个数组(CFMutableArrayRef)。也许它被意外地重新分配到某个地方。 -
好主意,本。我继续做了。您会看到我在创建
ipAddresses后并没有重新分配它 - 我只是使用CFArrayInsertValueAtIndex对其进行了变异。当我查看addressesForHostname中返回线上的数组时,它看起来是正确的。这让我相信__bridge_transfer是罪魁祸首,但我对免费桥接的经验并不多。
标签: ios objective-c return-value class-method toll-free-bridging