Есть ли в классе Facebook iPhone Facebook SDK метод отмены? - PullRequest
9 голосов
/ 20 января 2011

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

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

Ответы [ 2 ]

9 голосов
/ 25 мая 2011

Для тех, кто сталкивается с этим вопросом, похоже, что наблюдение Мэтта не относится к новейшей версии 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.

Обновление:

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

Обновление 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 в методах делегатов после обработки ответа.

7 голосов
/ 15 февраля 2011

РЕДАКТИРОВАТЬ Как указывалось в ответе Тима на этот вопрос, эта информация теперь устарела с последними выпусками Facebook iOS SDK.

Нетспособ отменить отложенный запрос.Однако это не должно вызывать сбой вашего приложения.

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

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

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

Атрибут assign в объявлении свойства создает впечатление, что он хранит слабый ref для вашего класса, но затем в 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;
}

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

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

...