2011-01-20 24 views
9

Có cách nào để hủy yêu cầu đang chờ xử lý của đối tượng Facebook không?Lớp Facebook của iPhone Facebook SDK có hủy phương pháp không?

Tôi không thể tìm thấy bất kỳ phương pháp nào trong Facebook.h hoặc cách truy cập đối tượng cơ bản NSURLConnection. Nếu tôi nhấn trở lại trên thanh điều hướng và yêu cầu của họ là một yêu cầu Facebook không đồng bộ đang chờ xử lý, yêu cầu sẽ cố gắng gửi một tin nhắn đến một số view được deallocated sau khi phản hồi đã đến, khiến ứng dụng gặp sự cố.

Trả lời

7

EDIT Như đã chỉ ra trong câu trả lời của Tim cho câu hỏi này, thông tin này bây giờ đã lỗi thời với các phiên bản mới nhất của Facebook iOS SDK.

Không có cách nào để hủy yêu cầu đang chờ xử lý. Tuy nhiên, điều này không nên làm hỏng ứng dụng của bạn.

Lớp Facebook sử dụng lớp FBRequest dưới mui xe để thực hiện tất cả các yêu cầu REST hoặc Graph API của nó và đây là lớp kết thúc với tham chiếu đến chế độ xem của bạn. Nhìn vào tiêu đề cho FBRequest:

@interface FBRequest : NSObject { 
    id<FBRequestDelegate> _delegate; 
    NSString*    _url; 
    NSString*    _httpMethod; 
    NSMutableDictionary* _params; 
    NSURLConnection*  _connection; 
    NSMutableData*  _responseText; 
} 

@property(nonatomic,assign) id<FBRequestDelegate> delegate; 

Thuộc tính assign trong việc kê khai tài sản làm cho nó có vẻ rằng nó lưu một yếu-ref đến lớp học của bạn, nhưng sau đó trong 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; 
} 

Nó rõ ràng giữ lại các đại biểu. Vì vậy, trong dòng chảy bình thường của ứng dụng của bạn, khi bạn nghĩ rằng bộ điều khiển xem của bạn nên được deallocated sau khi được popped tắt ngăn xếp chuyển hướng, FBRequest đã đảm bảo rằng nó vẫn sẽ được sống để nhận được phản ứng bằng cách lấy quyền sở hữu của nó.

Điều này khiến bạn có vẻ như có vấn đề về quản lý bộ nhớ khác ở nơi khác trong ứng dụng.

+0

Cảm ơn, Bạn đã lưu ngày của tôi. –

9

Đối với bất kỳ ai gặp phải câu hỏi này, có vẻ như quan sát của Matt không áp dụng cho facebook-iphone-sdk mới nhất. Các thông số được giữ lại không còn rõ ràng trong phương pháp có liên quan:

+ (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; 

Vì vậy, quản lý bộ nhớ cho các đại biểu rơi trở lại việc kê khai tài sản trong file .h:

@property(nonatomic,assign) id<FBRequestDelegate> delegate; 

Điều này có nghĩa một vụ tai nạn tại là có thể vì đối tượng đại biểu có thể được deallocated trước khi FBRequest được hoàn thành.

Cập nhật:

Sự chỉnh sửa có được đề xuất trong this câu hỏi để cho phép hủy bỏ FBRequests chờ giải quyết.

Cập nhật 2:

Để tránh một vụ tai nạn trong trường hợp các đại biểu được deallocated trước FBRequest kết thúc, bạn cần phải hủy bỏ kết nối các hoạt động FBRequest như bạn deallocate các đại biểu (mà về cơ bản là những gì Matt gợi ý trong câu hỏi được liên kết). Tuy nhiên (tôi không chắc chắn nếu điều này là mới), bạn có thể làm điều này trực tiếp đến FBRequest vì nó cho thấy nó là tài sản NSURLConnection.Vì vậy, nếu bạn giữ lại đối tượng FBRequest của bạn trong một sở hữu:

@property (nonatomic, retain) FBRequest *myRequest; 

và lưu các đối tượng yêu cầu khi bạn thực hiện cuộc gọi của bạn:

self.myRequest = [facebookObj requestWithGraphPath:@"me" andDelegate:self]; 

bạn có thể làm sạch tất cả mọi thứ trong dealloc của bạn:

- (void)dealloc 
{ 
if(myRequest) { 
    [[myRequest connection] cancel]; 
    [[myRequest release]; 
    } 

    ... 

    [super dealloc]; 
} 

Rõ ràng, bạn có lẽ cũng nên giải phóng và nil thuộc tính FBRequest trong các phương thức ủy nhiệm khi bạn đã xử lý phản hồi.

+1

Có [vấn đề mở] (https://github.com/facebook/facebook-ios-sdk/issues/220) về việc này. – albertamg

+0

Nhận xét bởi @ user1526896: Một cần thêm 'myRequest.delegate = nil;' để ngăn chặn sự cố ứng dụng. – Damon

Các vấn đề liên quan