Objective c 使用圆弧通过另一个对象传递代理
我有两门课,Objective c 使用圆弧通过另一个对象传递代理,objective-c,ios,cocoa-touch,delegates,Objective C,Ios,Cocoa Touch,Delegates,我有两门课,MPRequest和MPModel。 MPModel类有一个从核心数据存储中查找某些内容的方法,如果找不到,则创建一个MPRequest以通过标准HTTP请求检索它(MPModel中的方法是静态的,而不是实例方法) 我想要的是能够获得当前HTTP请求的进度。我知道如何做到这一点,但我对如何通知视图控制器有点困惑。我尝试创建一个协议,在MPRequest类中定义一个委托属性,更改MPModel中的方法以接受该委托,然后在创建该委托时将其传递给MPRequest 这很好,但是ARC会在请
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
是MPModel
的一个子类,但是findAllWithBlock:sortedBy:ascended: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只是一个
长的
存储响应的预期大小。让它工作起来了。这在一定程度上是线程的问题,核心数据线程在我的请求之前就结束了,我从一个完全不同的请求中查看输出,以及ARC处理内存块的方式
谢谢你们的帮助,伙计们看起来不错。当你说arc正在释放代理时,你的意思是即使视图控制器仍然存在,它也被设置为零吗?基本上是的。在MPRequest类中,我在HTTP请求接收数据时插入了一个NSLog来输出委托,它只是显示nil,即使应用程序当前正在显示该视图控制器:(@PaReeOhNos,在设置为objRequest之前,您如何将委托传递给此方法?它可能会自动释放。MPModel中的方法是findAllWithBlock:sortedBy:ascending:delegate:这是我最初传递它的位置,它被传递给
self
,因此不应释放self:(我想这里没有显示的代码一定是出了什么问题。如果您使属性变强,那么它会工作吗?
[_responseData appendData:data];
[_delegate requestDidReceive:(float)data.length ofTotal:_contentLength];