iPhone Facebook SDK 的 Facebook 类有取消方法吗?

Posted

技术标签:

【中文标题】iPhone Facebook SDK 的 Facebook 类有取消方法吗?【英文标题】:Does Facebook class of iPhone Facebook SDK have cancel method? 【发布时间】:2011-01-20 20:04:53 【问题描述】:

是否可以取消 Facebook 对象的待处理请求?

我在 Facebook.h 中找不到任何方法,也找不到访问底层 NSURLConnection 对象的方法。如果我按回导航栏并且它们是待处理的异步 Facebook 请求,则请求会在响应到来后尝试向已释放的 view 发送消息,从而导致应用程序崩溃。

【问题讨论】:

【参考方案1】:

对于遇到此问题的任何人,Matt 的观察似乎不适用于最新的 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 连接(这基本上是 Matt 在链接问题中建议的内容)。但是(我不确定这是否是新的),您可以直接对 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 属性。

【讨论】:

有一个open issue关于这个。 @user1526896 评论:需要添加myRequest.delegate = nil; 以防止应用程序崩溃。【参考方案2】:

编辑 正如 Tim 对这个问题的回答中所指出的,这些信息现在已经随着 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;

属性声明中的 assign 属性使它看起来像是为您的类存储了一个弱引用,但随后在 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 已确保它仍然可以通过获取它的所有权来接收响应。

这使您看起来可能在应用程序的其他地方存在其他内存管理问题。

【讨论】:

以上是关于iPhone Facebook SDK 的 Facebook 类有取消方法吗?的主要内容,如果未能解决你的问题,请参考以下文章

安装 Facebook SDK - iPhone

Android:facebook sdk注销问题?

出现错误'操作无法完成。 (com.facebook.sdk 错误 5.)' 从 iphone 在 facebook 上发布视频时

Facebook v3 sdk monodroid 绑定

为 iOS SDK 迁移 Facebook 身份验证凭据

iPhone Facebook SDK 的 Facebook 类有取消方法吗?