取消委托调用后返回FB和委托已dealloc'd

问题描述:

我张贴到用户的Facebook墙上用类似这样的代码:取消委托调用后返回FB和委托已dealloc'd

[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]; 

}

这不起作用!

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

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

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

例如,如果你在登录后到另一个页面:

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

的想法是这样的,它的工作原理,但不是很方便。

+0

这是否解决了在请求尚未完成时解除分配视图的问题? –

+0

由于在应用程序退出前,您的rootView或mainView中的视图没有被释放,所以这里的释放没有问题。 –

创建一个对象(与视图控制器分开),该对象将成为FB委托并且不会释放该对象。你可以在实例化调用FB的视图控制器的同一地方实例化它。 或者,如果您不关心退货状态,请不要使用委托。

如果你看看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代码这种方法无代表&它停止退出时,同时请求是活跃的,我具有崩溃。

我做了什么来克服这个问题是为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请求的唯一代表,并且永远不会通过您的程序释放,即使原始类被释放,也不会出现错误。

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

希望这有助于任何方式!

正确的解决方案是在调用GraphAPI时保存FBRequest对象。 因此,当你的班级被处理时,你将能够将它的委托属性设置为零。 因此清理你的乱七八糟,并避免由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]; 

设置它的委托propery为零你的类的dealloc方法:

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

    [super dealloc] 
}