0

我有 2 节课,MPRequest并且MPModel. 该类MPModel具有从核心数据存储中查找某些内容的方法,如果未找到,则创建一个MPRequest通过标准 HTTP 请求检索它的方法(该方法MPModel是静态的,而不是实例方法)。

我想要的是能够获得当前 HTTP 请求的进度。我知道如何做到这一点,但我对如何通知视图控制器有点卡住了。我尝试创建一个协议,在MPRequest类中定义一个委托属性,更改方法MPModel以接受此委托,然后将其传递给MPRequest它的创建时。

这很好,但是 ARC 会在请求运行时释放这个委托,因此不会做我想要的。我试图避免让我的委托对象成为强引用,以防它抛出任何引用循环,但我不知道有任何其他方法可以做到这一点。

要启动请求,从我正在运行的视图控制器

[MPModel findAllWithBlock:^(NSFetchedResultsController *controller, NSError *error) {
    ....
} sortedBy:@"name" ascending:YES delegate:self]

在 findAllWithBlock 方法中,我有

MPRequest *objRequest = [MPRequest requestWithURL:url];
  objRequest.delegate = delegate;

[objRequest setRequestMethod:@"GET"];
[MPUser signRequest:objRequest];

[objRequest submit:^(MPResponse *resp, NSError *err) {
    ...
}

MPRequest课堂上,我定义了以下属性:

@property (nonatomic, weak) NSObject<MPRequestDelegate> *delegate;

有什么想法或建议吗?

根据要求,这里有更多关于如何调用事物的代码:

在视图控制器中:

[MPPlace findAllWithBlock:^(NSFetchedResultsController *controller, NSError *error) {
        _placesController = controller;
        [_listView reloadData];
        [self addAnnotationsToMap];
        [_loadingView stopAnimating];

        if (_placesController.fetchedObjects.count > 0) {
            // We've got our places, but if they're local copies
            // only, new ones may have been added so just update
            // our copy
            MPSyncEngine *engine = [[MPSyncEngine alloc] initWithClass:[MPPlace class]];
                 engine.delegate = self;
            [engine isReadyToSync:YES];
            [[MPSyncManager sharedSyncManager] registerSyncEngine:engine];
            [[MPSyncManager sharedSyncManager] sync];
        }
    } sortedBy:@"name" ascending:YES delegate:self];

在这里,由于明显的原因, self 永远不会被释放,所以我不明白这是怎么回事。

上面,MPPlace是 的子类MPModel,但实现findAllWithBlock:sortedBy:ascending:delegate:完全在MPModel

里面的方法MPModel是这样的

NSManagedObjectContext *context = [[MPCoreDataManager sharedInstance] managedObjectContext];
[context performBlockAndWait:^{
    __block NSError *error;
    NSFetchRequest *request = [[NSFetchRequest alloc] initWithEntityName:NSStringFromClass([self class])];
    [request setSortDescriptors:@[[[NSSortDescriptor alloc] initWithKey:key ascending:asc]]];

    NSFetchedResultsController *controller = [[NSFetchedResultsController alloc] initWithFetchRequest:request
                                                                                 managedObjectContext:context
                                                                                   sectionNameKeyPath:nil
                                                                                            cacheName:nil];

    [controller performFetch:&error];

    if (!controller.fetchedObjects || controller.fetchedObjects.count == 0) {
        // Nothing found or an error, query the server instead
                NSString *url = [NSString stringWithFormat:@"%@%@", kMP_BASE_API_URL, [self baseURL]];
        MPRequest *objRequest = [MPRequest requestWithURL:url];
          objRequest.delegate = delegate;

        [objRequest setRequestMethod:@"GET"];
        [MPUser signRequest:objRequest];

        [objRequest submit:^(MPResponse *resp, NSError *err) {
            if (err) {
                block(nil, err);
            } else {
                NSArray *objects = [self createListWithResponse:resp];
                         objects = [MPModel saveAllLocally:objects forEntityName:NSStringFromClass([self class])];
                [controller performFetch:&error];
                block(controller, nil);
            }
        }];
    } else {
        // Great, we found something :)
        block (controller, nil);
    }
}];

委托只是被传递给MPRequest正在创建的对象。我最初担心的是正在创建的 MPRequest 对象是由 ARC 释放的(我猜可能是这样),但是当我更改它时它并没有解决任何问题。我无法将其设为 iVar,因为该方法是静态的。

请求的提交方法如下所示:

_completionBlock = block;
   _responseData = [[NSMutableData alloc] init];

[self prepareRequest];

[self prepareRequestHeaders];
_connection = [[NSURLConnection alloc] initWithRequest:_urlRequest
                                              delegate:self];

当应用程序开始下载数据时,它会调用:

[_responseData appendData:data];
[_delegate requestDidReceive:(float)data.length ofTotal:_contentLength];

其中 _contentLength 只是long存储响应的预期大小。

4

1 回答 1

0

得到它的工作。这部分是线程问题,核心数据线程在我的请求之前结束,我完全查看来自不同请求的输出,以及 ARC 以块为单位处理内存的方式。

谢谢你们的帮助

于 2013-01-08T23:36:25.140 回答