You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Objective-C:修改方法返回带IPv4/IPv6键的NSDictionary

修正方案:将服务地址转为IPv4/IPv6键值对字典

你的代码思路方向正确,但存在一个关键逻辑错误,导致所有地址都会被错误归类到IPv4键下:NSString *key = AF_INET ? @"IPv4" : @"IPv6"; 这行直接用AF_INET作为判断条件,而AF_INET是一个非零常量(值为2),条件永远为真,因此永远返回@"IPv4"。

下面是修正后的完整代码:

+ (NSDictionary<NSString *, NSString *> *)addressesFromService:(NSNetService *)service
{
    NSMutableDictionary<NSString *, NSString *> *result = [NSMutableDictionary dictionary];
    
    char addressBuffer[INET6_ADDRSTRLEN];
    
    for (NSData *data in service.addresses) {
        memset(addressBuffer, 0, INET6_ADDRSTRLEN);

        typedef union {
            struct sockaddr sa;
            struct sockaddr_in ipv4;
            struct sockaddr_in6 ipv6;
        } ip_socket_address;

        ip_socket_address *socketAddress = (ip_socket_address *)[data bytes];

        if (socketAddress && (socketAddress->sa.sa_family == AF_INET || socketAddress->sa.sa_family == AF_INET6)) {
            const char *addressStr = inet_ntop(
                socketAddress->sa.sa_family,
                (socketAddress->sa.sa_family == AF_INET ? (void *)&(socketAddress->ipv4.sin_addr) : (void *)&(socketAddress->ipv6.sin6_addr)),
                addressBuffer,
                sizeof(addressBuffer)
            );

            if (addressStr) {
                // 修正:根据当前地址的协议族选择对应键
                NSString *key = (socketAddress->sa.sa_family == AF_INET) ? @"IPv4" : @"IPv6";
                result[key] = [NSString stringWithUTF8String:addressStr];
            }
        }
    }

    return [result copy];
}

额外说明

如果一个服务可能存在多个同类型IP地址(比如多个IPv4或IPv6),上面的代码会用最后一个地址覆盖之前的。如果需要保留所有同类型地址,可以把字典的值类型改为数组,修改后的代码如下:

+ (NSDictionary<NSString *, NSArray<NSString *> *> *)addressesFromService:(NSNetService *)service
{
    NSMutableDictionary<NSString *, NSMutableArray<NSString *> *> *result = [NSMutableDictionary dictionary];
    
    char addressBuffer[INET6_ADDRSTRLEN];
    
    for (NSData *data in service.addresses) {
        memset(addressBuffer, 0, INET6_ADDRSTRLEN);

        typedef union {
            struct sockaddr sa;
            struct sockaddr_in ipv4;
            struct sockaddr_in6 ipv6;
        } ip_socket_address;

        ip_socket_address *socketAddress = (ip_socket_address *)[data bytes];

        if (socketAddress && (socketAddress->sa.sa_family == AF_INET || socketAddress->sa.sa_family == AF_INET6)) {
            const char *addressStr = inet_ntop(
                socketAddress->sa.sa_family,
                (socketAddress->sa.sa_family == AF_INET ? (void *)&(socketAddress->ipv4.sin_addr) : (void *)&(socketAddress->ipv6.sin6_addr)),
                addressBuffer,
                sizeof(addressBuffer)
            );

            if (addressStr) {
                NSString *key = (socketAddress->sa.sa_family == AF_INET) ? @"IPv4" : @"IPv6";
                // 初始化数组(如果不存在)
                if (!result[key]) {
                    result[key] = [NSMutableArray array];
                }
                [result[key] addObject:[NSString stringWithUTF8String:addressStr]];
            }
        }
    }

    return [result copy];
}

内容的提问来源于stack exchange,提问作者Jerry Seigle

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 11:50:30