Назначение из метода Class связывает класс вместо его возвращаемого значения

Я заметил что-то странное в поведении кода, который я сейчас пишу, и подумал, что я попрошу здесь посмотреть, не делаю ли я что-нибудь глупое, что может привести к этому.

По сути, когда я присваиваю переменную возвращаемому значению моего метода класса, вместо переменной, содержащей ссылку на возвращаемое значение, она содержит ссылку на класс. Смотрите код ниже:

NSArray * newAddresses = [MyHost addressesForHostname: @"google.com"];

Который имеет сигнатуру метода

+ (NSArray *) addressesForHostname: (NSString *)hostname

И возвращает

return (__bridge_transfer NSArray *) ipAddresses; // ipAddresses is a CFMutableArrayRef

Как видите, я использую бесплатное мостовое соединение для использования объектов CoreFoundation, так как собираю список IP-адресов для некоторых сетевых интерфейсов.

После newAddresses был назначен, я смотрю на класс newAddresses массив в LLDB и получить:

(lldb) po [newAddresses class]
MyHost

Я ошибаюсь в своих предположениях о том, как я использую __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;
}

1 ответ

Итак, я нашел решение, и оно лежит во мне, забыв инициализировать ipAddresses = nil прежде чем что-то случится. Как написан этот код, он не будет присваивать значение ipAddresses если он не может решить hostRef дано CFHostStartInfoResolution, Без значения в ipAddresses, он возвращает неинициализированный указатель, который был приведен и передан его владельцу.

Я не могу найти официальную документацию, в которой говорится об этом, но я считаю, что это будет неопределенное поведение.

Я должен заявить, что если кто-то использует этот код в качестве ссылки, у меня возникают противоречивые сбои на линии, где я выпускаю hostRef, Это не связано с проблемой, которую я создал для этой темы, но на нее стоит обратить внимание.

Другие вопросы по тегам