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 类有取消方法吗?的主要内容,如果未能解决你的问题,请参考以下文章
出现错误'操作无法完成。 (com.facebook.sdk 错误 5.)' 从 iphone 在 facebook 上发布视频时