FB返回并取消委托后取消委托调用

时间:2011-11-22 10:55:04

标签: ios facebook facebook-graph-api

我发布的用户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 个答案:

答案 0 :(得分:1)

正确的解决方案是在调用GraphAPI时保存FBRequest对象。 因此,当您的类被释放时,您将能够将其委托属性设置为nil。 因此,清理你的混乱,避免SDK的respondsToSelector方法导致崩溃。

首先在class.h中声明一个FBRequest属性:

@property (nonatomic, retain) FBRequest *fbRequest;

在class.m中合成它:

@synthesize fbRequest;

在您调用图形API时设置它:

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

在你的班级的dealloc方法中将它的委托属性设置为nil:

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

    [super dealloc]
}

答案 1 :(得分:0)

我有一个解决方案,但不是很方便;

我在同一个视图控制器中有两个独立的视图,其中一个是您请求发布的视图,另一个是目标视图。

您只需在请求完成后隐藏其中一个视图。或者隐藏另一个并在请求时显示一个。

例如,如果您在登录后前往其他页面:

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

这个想法是这样的,它有效但不太方便。

答案 2 :(得分:0)

创建一个将成为FB委托的对象(与视图控制器分开),不要释放它。您可以从实例化调用FB的视图控制器的同一位置实例化它。 或者,如果您不关心返回状态,请不要使用委托。

答案 3 :(得分:0)

如果你看看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代码中使用这种方法来代表代表和当请求处于活动状态时,它停止了我退出时遇到的崩溃。

答案 4 :(得分:0)

我为克服这个问题所做的是为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收到请求的响应时,它会将其传递给原始类。 Ans因为它是每个FB请求的唯一代表,并且永远不会通过您的程序解除分配,即使原始类被解除分配,也不会出现错误。

作为所有这些的奖励,如果不需要,你会自动失去那些你不需要实施的方法的警告。

希望这会有所帮助!