【问题标题】:Using blocks within blocks in Objective-C: EXC_BAD_ACCESS在 Objective-C 的块中使用块:EXC_BAD_ACCESS
【发布时间】:2011-12-28 22:48:23
【问题描述】:

使用 iOS 5 的新 TWRequest API,我遇到了与块使用相关的砖墙。

我需要做的是在收到对第一个请求的成功响应后,立即触发另一个请求。在第二个请求的完成块上,我然后通知多步操作的成功或失败。

这大概是我在做什么:

- (void)doRequests
{
    TWRequest* firstRequest = [self createFirstRequest];
    [firstRequest performRequestWithHandler:^(NSData* responseData,
                                              NSHTTPURLResponse* response,
                                              NSError* error) {
        // Error handling hidden for the sake of brevity...
        TWRequest* secondRequest = [self createSecondRequest];
        [secondRequest performRequestWithHandler:^(NSData* a,
                                                   NSHTTPURLResponse* b,
                                                   NSError* c) {
            // Notify of success or failure - never reaches this far
        }];
    }];
}

我不会保留任何请求或在任何地方保留对它们的引用;就是一劳永逸。

但是,当我运行该应用程序时,它会在 EXC_BAD_ACCESS on 时崩溃:

[secondRequest performRequestWithHandler:...];

它执行第一个请求很好,但是当我尝试使用处理程序启动第二个请求时,它崩溃了。这段代码有什么问题?


创建请求的方法很简单:

- (TWRequest*)createFirstRequest
{
    NSString* target   = @"https://api.twitter.com/1/statuses/home_timeline.json";
    NSURL* url         = [NSURL URLWithString:target];
    TWRequest* request = [[TWRequest alloc]
                          initWithURL:url parameters:params
                          requestMethod:TWRequestMethodGET];
    // _twitterAccount is the backing ivar for property 'twitterAccount',
    // a strong & nonatomic property of type ACAccount*
    request.account    = _twitterAccount;

    return request;
}

【问题讨论】:

  • 请发createFirstRequestcreateSecondRequest的代码
  • 你能把-createSecondRequest的代码贴出来吗?我猜这段代码在后台线程上运行存在问题,因为无法保证完成处理程序将在哪个线程上运行。
  • 完成;抱歉,我认为这无关紧要。
  • @brunodecarvalho:如果您想了解相关内容,请在需要发布示例代码时创建minimal test case

标签: objective-c cocoa-touch uikit objective-c-blocks twrequest


【解决方案1】:

确保您保留引用/保留拥有 ACAccountACAccountStore,您用于签署 TWRequests。

如果您不这样做,ACAccount 将变为无效,然后您将在尝试触发使用它签名的 TWRequest 时获得 EXC_BAD_ACCESS。

【讨论】:

  • 谢谢!但是感觉有点别扭。您需要保存对您不打算在 Twitter 请求对象中设置的对象的引用。非常容易出错。
  • 我什至没有尝试向 Twitter 发出任何请求,只是在设备上抓取了一系列用户,而我终其一生都无法弄清楚为什么我在 ACAccount 上的访问权限不佳...... @Property(nonatomic,retain)ACAccountStore *store;是答案!谢谢你弗雷德!
【解决方案2】:

我对 TW* 不熟悉,所以认为这是一个疯狂的猜测......尝试发送一个堆分配的块:

[firstRequest performRequestWithHandler:[^ (NSData *responseData, ...) {
  ...
} copy]];

澄清一下,我认为你发送的块是堆分配的,所以虽然 TW* 可能会保留它,但如果它已经超出范围,它不会有任何区别.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-03
    • 1970-01-01
    • 2017-12-15
    • 2011-12-15
    • 1970-01-01
    相关资源
    最近更新 更多