Отменить делегатский вызов после того, как FB вернулся и делегат был освобожден - PullRequest
0 голосов
/ 22 ноября 2011

Я публикую на стене Facebook пользователей код, подобный следующему:

[appDelegate.facebook requestWithGraphPath:@"me/feed" 
              andParams:params
          andHttpMethod:@"POST"
            andDelegate:self];

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

Вот хорошее описание проблемы, с которой я столкнулся: https://github.com/facebook/facebook-ios-sdk/issues/220

- (void)dealloc {
appDelegate.facebook.sessionDelegate = nil;
[super dealloc];

}

Это не работает!

Ответы [ 5 ]

1 голос
/ 10 января 2013

Правильным решением является сохранение объекта FBRequest при вызове GraphAPI. Таким образом, вы сможете установить его свойство делегата равным nil, когда ваш класс освобождается. Таким образом, очистите свой беспорядок и избегайте сбоев, вызванных методом отклика SDKoSelector SDK.

Сначала объявите свойство FBRequest в вашем class.h:

@property (nonatomic, retain) FBRequest *fbRequest;

Синтезируйте это в своем классе. M:

@synthesize fbRequest;

Установите его при вызове API графа следующим образом:

fbRequest = [appDelegate.facebook requestWithGraphPath:@"me/feed" 
              andParams:params
          andHttpMethod:@"POST"
            andDelegate:self];

Установите значение делегата равным nil в методе dealloc вашего класса:

-(void) dealloc
{
    fbRequest.delegate = nil;
    [fbRequest release];
    .
    .
    .

    [super dealloc]
}
0 голосов
/ 19 июля 2012

Что я сделал, чтобы преодолеть эту проблему, так это создать класс-оболочку для FB, который я назвал «FacebookManager».Он отвечает за каждый запрос FB, выполненный в вашей заявке.Будучи одноэтапным приложением, его жизненный цикл длится также на протяжении всей жизни приложения.

@protocol
@optional
-(void)fbDidLogin;
-(void)fbDidNotLogin:(BOOL)cancelled;
-(void)fbDidExtendToken:(NSString *)accessToken expiresAt:(NSDate *)expiresAt;
-(void)fbDidLogout;
-(void)fbSessionInvalidated;
-(void)request:(FBRequest *)request didLoad:(id)result;

@end

@interface FacebookManager : Facebook <FBSessionDelegate, FBRequestDelegate>

+(FacebookManager *)sharedFacebookInstance;
-(void)setFacebookDelegate:(id)delegate;
-(void)requestWithGraphPath:(NSString *)fbPath;

Другие классы, обычно ViewControllers, могут быть делегатом FacebookManager (или, при необходимости, вы можете создать массивделегаты при обработке одновременных запросов).Когда FacebookManager получает ответ от запроса, он передает его исходному классу.Кроме того, поскольку он является единственным делегатом для каждого запроса FB и никогда не освобождается из вашей программы, даже когда исходный класс освобождается, ошибок не возникает.

В качестве бонуса ко всему этому вы автоматически теряете эти предупреждениядля методов, которые вы не должны реализовывать, если не хотите.

Надеюсь, это поможет в любом случае!

0 голосов
/ 05 декабря 2011

Создайте объект (отдельный от контроллера представления), который будет делегатом FB, и не освобождайте его.Вы можете создать его из того же места, где вы создали экземпляр контроллера представления, который вызывает FB.Или, если вас не волнует статус возврата, не используйте делегата.

0 голосов
/ 22 июня 2012

Если вы посмотрите, как собственный код Facebook справляется с этим в Facebook.m, они создают список для хранения _request объектов 'NSMutableSet * _requests;'

, а это alloc / init'd и добавленные запросыкогда вы делаете звонки, они убирают их все при очистке.Смотрите строки с '[_requests addObject: _request];'и посмотрите на dealloc, где вы увидите: -

  for (FBRequest* _request in _requests) 
{
_request.delegate = nil;
[_request removeObserver:self forKeyPath:requestFinishedKeyPath];
 }

Я использовал этот подход в своем собственном коде FB, чтобы обнулить делегатов, и он остановил сбои, которые у меня были при выходе, когда был активен запрос.*

0 голосов
/ 05 декабря 2011

У меня было решение для этого, но не очень удобное;

У меня есть 2 отдельных представления в одном контроллере представления, где одно из них - это то, которое вы запрашиваете для публикации, другое - представление назначения.

Вы просто скрываете одно из представлений после завершения запроса.Или скрыть другой и отобразить его во время запроса.

Например, если вы заходите на другую страницу после входа в систему:

- (void)fbDidLogin {
// Do necessary stuff
           self.secondView.hidden = YES;
           self.view.hidden = NO;
}

Идея такая, она работает, но не оченьудобный.

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