Случайный вызов одного и того же объекта obj-C дважды - PullRequest
1 голос
/ 04 августа 2009

Я хочу сделать два отдельных асинхронных поиска в Интернете. Однако они наступают друг на друга, и я не знаю, почему.

Когда я копаюсь, кажется, что оба поиска работают на одном и том же объекте (симптом: второй вызов сбрасывает значение thisPage, установленное первым вызовом).

Может быть, это как-то связано с использованием делегата (все еще неудобно в этой области)?


Я создал класс CSNet и инициализирую его:

CSNet               *startupPage;
CSNet               *positionUpdatePage;
startupPage = [[CSNet alloc] init];
positionUpdatePage = [[CSNet alloc] init];

Позже я пытаюсь использовать каждый объект:

[startupPage getPage:self page:pageName];

и

[positionUpdatePage getPage:self page:pageName];

переменная уровня модуля:

enum pageType {nothing, startup, positionUpdate, acquireOpponents, fire, changeCredentials};
enum pageType thisPage;

вызов getPage:

-(void)getPage:(id)delegate page:(NSString *)page {
m_Delegate = delegate;
if ([[page substringToIndex:2] isEqual:@"st"]) {
        thisPage = startup;
} else {
    if ([[page substringToIndex:2] isEqual:@"pu"]) {
        thisPage = positionUpdate;
    } else {
        if ([[page substringToIndex:2] isEqual:@"ao"]) {
            thisPage = acquireOpponents;
        } else {
            if ([[page substringToIndex:2] isEqual:@"fi"]) {
                thisPage = fire;
            } else {
                if ([[page substringToIndex:2] isEqual:@"cc"]) {
                    thisPage = changeCredentials;
                }   
            }
        }
    }
}   

NSURLRequest *startupRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:[
    [NSString stringWithFormat: @"%@%@", SERVER, page] 
    stringByReplacingOccurrencesOfString:@" " withString:@"%20"]]];
startupConnection = [[NSURLConnection alloc] initWithRequest:startupRequest delegate:self];

if(startupConnection)
{
    workInProgress = YES;
    m_RequestData = [[NSMutableData data] retain];
}
 }

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{

// this method is called when the server has determined that it
// has enough information to create the NSURLResponse
// it can be called multiple times, for example in the case of a
// redirect, so each time we reset the data.
// receivedData is declared as a method instance elsewhere
[m_RequestData setLength:0];

}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data 
{
// append the new data to the receivedData
// receivedData is declared as a method instance elsewhere
[m_RequestData appendData:data];    
}

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
// release the data object
[m_RequestData release];

// inform the user
NSLog(@"Connection failed! Error - %@ %@", [error localizedDescription], [[error userInfo] objectForKey:NSErrorFailingURLStringKey]);
workInProgress = NO;
}

возвращение к делегату:

 - (void)connectionDidFinishLoading:(NSURLConnection *)connection {
if(workInProgress == YES) {
    workInProgress = NO;
    switch (thisPage) {
        case startup:
            //if ([m_Delegate respondsToSelector:@selector(startupReady:)])
                [m_Delegate startupReady:m_RequestData];
            break;
        case positionUpdate:
            //if ([m_Delegate respondsToSelector:@selector(positionUpdateReady:)])
                [m_Delegate positionUpdateReady:m_RequestData];
            break;
        case acquireOpponents:
            //if ([m_Delegate respondsToSelector:@selector(opponentsReady:)])
                [m_Delegate opponentsReady:m_RequestData];
            break;
        case fire:
            //if ([m_Delegate respondsToSelector:@selector(fireReady:)])
                [m_Delegate fireReady:m_RequestData];
            break;
        case changeCredentials:
            //if ([m_Delegate respondsToSelector:@selector(changeCredentialsReady:)])
                [m_Delegate changeCredentialsReady:m_RequestData];
            break;
        default:
            break;
    }
    [m_RequestData release];
}   
}

Ответы [ 2 ]

4 голосов
/ 04 августа 2009

Вы сказали, что thisPage - переменная уровня модуля. Я предполагаю, что это означает, что это не переменная экземпляра. В этом случае существует только одна переменная thisPage, общая для всех экземпляров CSNet. Естественно, если у вас работает два из них одновременно, они будут разламывать друг друга.

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

2 голосов
/ 04 августа 2009

Вы можете отслеживать, какой объект отправляет методы делегату, и четко обрабатывать два соединения в одном и том же объекте делегата. Если вы посмотрите на сигнатуру метода для методов делегата, таких как -connection:didReceiveResponse:, первый параметр - это соединение, которое отправляет сообщение. В вашем случае это будет один из двух объектов, которые вы создаете, дважды вызывая -getPage:page:. Поэтому следите за этими объектами и проверяйте, какой из них вызывает метод (ы) делегата.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...