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

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

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

【问题讨论】:

    标签: iphone objective-c facebook iphone-sdk-3.0


    【解决方案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 已确保它仍然可以通过获取它的所有权来接收响应。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-09-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多