2011-01-20 3 views
9

Есть ли способ отменить ожидающий запрос объект Facebook?Есть ли у Facebook класс iPhone Facebook SDK метод отмены?

Я не могу найти какие-либо методы в Facebook.h или способ доступа к базовому объекту NSURLConnection. Если я вернусь на панель навигации, а их ожидает асинхронный запрос Facebook, запрос попытается отправить сообщение освобожденному view после того, как ответ пришел, в результате чего приложение сбой.

ответ

7

EDIT Как указано в ответе Тима на этот вопрос, эта информация является устаревшим с новейшими выпусками Facebook IOS SDK.

Невозможно отменить ожидающий запрос запрос. Однако это не должно разрушать ваше приложение.

Класс Facebook использует класс FBRequest под капотом, чтобы выполнить все его запросы REST или Graph API, и это класс, который заканчивается ссылкой на ваш вид (контроллер?) В качестве его свойства делегирования. Глядя на заголовок для FBRequest:

@interface FBRequest : NSObject { 
    id<FBRequestDelegate> _delegate; 
    NSString*    _url; 
    NSString*    _httpMethod; 
    NSMutableDictionary* _params; 
    NSURLConnection*  _connection; 
    NSMutableData*  _responseText; 
} 

@property(nonatomic,assign) id<FBRequestDelegate> delegate; 

правопреемником атрибут в объявлении свойства делает его, кажется, что он хранит слабый-реф в своем классе, но потом в FBRequest.m:

+ (FBRequest *)getRequestWithParams:(NSMutableDictionary *) params 
         httpMethod:(NSString *) httpMethod 
          delegate:(id<FBRequestDelegate>) delegate 
         requestURL:(NSString *) url { 
    FBRequest* request = [[[FBRequest alloc] init] autorelease]; 
    request.delegate  = [delegate retain]; // <- It's retained! (Comment mine) 
    request.url   = [url retain]; 
    request.httpMethod = [httpMethod retain]; 
    request.params  = [params retain]; 
    request.connection = nil; 
    request.responseText = nil; 

    return request; 
} 

It четко сохраняет делегата. Таким образом, при нормальном потоке вашего приложения, когда вы считаете, что ваш контроллер просмотра должен быть освобожден после того, как его удалили из навигационного стека, FBRequest обеспечил, чтобы он все еще был жив, чтобы получить ответ, взяв на себя ответственность за него.

Это похоже на то, что у вас могут быть другие проблемы с управлением памятью в другом месте приложения.

+0

Спасибо, Ты спас мой день. –

9

Для всех, кто сталкивается с этим вопросом, кажется, что наблюдение Мэтта не относится к новейшей facebook-iphone-sdk. Параметры больше не являются явно сохраняются в соответствующем методе:

+ (FBRequest *)getRequestWithParams:(NSMutableDictionary *) params 
         httpMethod:(NSString *) httpMethod 
          delegate:(id<FBRequestDelegate>) delegate 
         requestURL:(NSString *) url { 

    FBRequest* request = [[[FBRequest alloc] init] autorelease]; 
    request.delegate = delegate; 
    request.url = url; 
    request.httpMethod = httpMethod; 
    request.params = params; 
    request.connection = nil; 
    request.responseText = nil; 

Так управление памятью для делегата падает обратно в объявлении свойства в файле .h:

@property(nonatomic,assign) id<FBRequestDelegate> delegate; 

Это означает, что авария сейчас так как объект делегата может быть освобожден до завершения FBRequest.

Update:

Возможный способ обхода предлагается в this вопрос разрешить отмену ожидающих FBRequests.

Update 2:

Чтобы избежать столкновения в случае, когда делегат получает высвобождены прежде, чем заканчивает FBRequest, вам нужно отменить подключение активного FBRequest как вы освободить делегата (который является в основном то, что говорит Мэтт в связанном вопросе). Однако (я не уверен, что это новое), вы можете сделать это непосредственно в FBRequest, поскольку оно предоставляет его свойство NSURLConnection.Таким образом, если вы сохраняете свой объект FBRequest в свойстве:

@property (nonatomic, retain) FBRequest *myRequest; 

и сохранить объект запроса, когда вы делаете ваш звонок:

self.myRequest = [facebookObj requestWithGraphPath:@"me" andDelegate:self]; 

вы можете очистить все в вашем dealloc:

- (void)dealloc 
{ 
if(myRequest) { 
    [[myRequest connection] cancel]; 
    [[myRequest release]; 
    } 

    ... 

    [super dealloc]; 
} 

Очевидно, что вы должны, вероятно, также освободить и присвоить значение свойства FBRequest в методах делегатов после обработки ответа.

+1

Об этом [открытая проблема] (https://github.com/facebook/facebook-ios-sdk/issues/220). – albertamg

+0

Комментарий от пользователя @ user1526896: нужно добавить 'myRequest.delegate = nil;', чтобы предотвратить сбой приложения. – Damon

Смежные вопросы