NSUrlConnection в NSThread - делегат не выполняется! - PullRequest
5 голосов
/ 22 февраля 2011

Я использую NSURLConnection в NSThread, но ни один из методов делегата NSURLConnection не выполняется! У меня есть основной метод в моем подклассе NSTread и цикл while, который поддерживает активный поток. Любая помощь?

Извините за весь этот код, но я думаю, что это лучший способ описать мою проблему. Так что это объект, который выполняет асинхронное соединение, вызывая createConnectionWithPath:userObjectReference

@interface WSDAsyncURLConnection : NSObject 
{
    NSMutableData *receivedData;
    NSDate *connectionTime;
    NSURLConnection *connection;

    id _theUserObject;

}


@property (nonatomic, retain) NSMutableData *receivedData;
@property (nonatomic, retain) NSDate *connectionTime;
@property (nonatomic, assign) NSURLConnection *connection;

- (void)createConnectionWithPath:(NSString *)thePath userObjectReference:(id)userObject;


@end


#import "WSDAsyncURLConnection.h"

@implementation WSDAsyncURLConnection
@synthesize connectionTime, receivedData, connection;


- (void) terminate
{
    if (self.connection) {
        [self.connection release];
        self.connection = nil;
    }
}   


- (void) createConnectionWithPath:(NSString *)thePath userObjectReference:(id)userObject;
{   
    _theUserObject = userObject;


    NSURLRequest *theRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:thePath]
                                                cachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData timeoutInterval:60];


    self.connection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self startImmediately:YES];

    if (self.connection) 
    {
        /* record the start time of the connection */
        self.connectionTime = [NSDate date];

        /* create an object to hold the received data */
        self.receivedData = [NSMutableData data];
    } 
}


- (void) connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
    [self.receivedData setLength:0];   
}

- (void) connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
    /* appends the new data to the received data */ 
    [self.receivedData appendData:data];
}

- (void) connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{    
    [self terminate];
}


- (void) connectionDidFinishLoading:(NSURLConnection *)connection
{
    // displays the elapsed time in milliseconds
    NSTimeInterval elapsedTime = [[NSDate date] timeIntervalSinceDate:self.connectionTime];
    // displayes the length of data received
    NSUInteger length = [self.receivedData length];

    NSString* aStr = [[NSString alloc] initWithData:receivedData encoding:NSASCIIStringEncoding];   

    [self terminate];


    [[NSNotificationCenter defaultCenter] postNotificationName:WSDAsynchURLConnectionDidFinished
                                                        object:_theUserObject 
                                                      userInfo:[NSDictionary dictionaryWithObject:aStr forKey:@"urlResponseString"]];

    NSLog(@"ti=%f, l=%d, response=%@", elapsedTime, length, aStr);

}

@end

Этот код в основном взят из примера проекта Apple, и он отлично работает вне NSThread. Но когда я использую его в следующем подклассе потока, метод делегата не выполняется !!

@implementation IncomingThread



- (void) main {

    NSAutoreleasePool *poool = [[NSAutoreleasePool alloc] init];


// I start the URLConnection here ... But no delegate is executed !
        [urlConn createConnectionWithPath:@"http://localhost:8888" userObjectReference:nil];


    while (![self isCancelled]) {

        [NSThread sleepForTimeInterval:3.];
    }


    [poool release];

}


- (id) init
{
    self = [super init];
    if (self != nil) {

        urlConn = [[WSDAsyncURLConnection alloc] init];
    }
    return self;
}


- (void) dealloc {

    NSLog(@"deallocating (%@)...", [self className]);


    [urlConn release];

    [super dealloc];
}

Ответы [ 4 ]

3 голосов
/ 22 февраля 2011

Прежде всего: вам не нужно использовать NSURLConnection в отдельном потоке.Поскольку он асинхронный, он не блокирует основной поток.Второе: нет обработки вашего соединения, потому что вы всегда останавливаете выполнение цикла выполнения потока с таким кодом:

 while (![self isCancelled]) {
        [NSThread sleepForTimeInterval:3.];
    }

Из документов для sleepForTimeInterval:

No run loop processing occurs while the thread is blocked.
1 голос
/ 22 февраля 2011

Вы делаете это трудным путем. NSURLConnection не очень хорошо работает с потоками, так как для работы требуется цикл выполнения. В вашем потоке нет цикла выполнения, и поэтому код не работает. Почему бы не запустить соединение в главном потоке? Или вы можете заключить соединение в NSOperation, пример кода здесь . И в настоящее время у вас также есть возможность использовать синхронное соединение и отправлять его в глобальную очередь GCD.

0 голосов
/ 18 мая 2011

Поздно, но это может спасти жизнь другим:)

Ссылка на решение: методы удаления NSURLConnection не работают

0 голосов
/ 22 февраля 2011

Вы помните, чтобы назначить делегата?

Что-то вроде:

self.connection.delegate = self;

То, что ваш класс WSDAsyncURLConnection реализует методы делегата, не означает, что они вызываются.

...