我正在使用块来执行与网络相关的任务
当块在我的UITableViewController
中完成时,我想重新加载tableviewcontroller
__unsafe_unretained UITableView *unretTableView = self.tableview;
[myRequest postWithCompletion:(bool finished) {
[unretTableView reloadData];
}];
这很好,除非我在请求完成之前离开(deallocate
)UITableViewController
我似乎指向一个解除分配的对象(unretTableView
)消息发送到解除分配的实例,即使在[UITableViewController dealloc]
方法(正在调用)中,我设置了self.tableview = nil;
其他详情:
__weak
,我定位的是iOS 4.3及以上版本UITableViewController
的{{1}}方法中,我设置dealloc
谢谢!
答案 0 :(得分:1)
鉴于您的意见,我可能倾向于追求NSOperationQueue
。这样你就可以
创建背景NSOperationQueue
;
如果您的下载允许一定数量的同时下载,您可以设置maxOperationCount
(或者如果您想要连续下载,请将其设置为1)。
当您启动后台作业时,您可以创建NSOperation
个对象,或者直接通过addOperationWithBlock
通过块提交NSOperationQueue
。如果您希望能够检查isCancelled
标志,则可能需要执行前者。
在尝试更新视图控制器之前,每个操作都可以检查是否已取消。
当视图控制器被解除时,它可以执行简单的cancelAllOperations
来取消排队的所有内容。
这是一个随机的例子:
- (void)viewDidLoad
{
[super viewDidLoad];
self.queue = [[NSOperationQueue alloc] init];
self.queue.maxConcurrentOperationCount = 4;
// let's add 100 operations to our queue
for (NSInteger i = 0; i < 100; i++)
{
NSBlockOperation *operation = [[NSBlockOperation alloc] init];
__unsafe_unretained NSBlockOperation *weakOperation = operation; // it seems vaguely disturbing to do this with __unsafe_unretained, but given that the operation queue is taking care of this for us, I believe it's ok
[operation addExecutionBlock:^{
NSLog(@"Beginning operation %d", i);
sleep(10);
if ([weakOperation isCancelled])
NSLog(@"Operation cancelled %d", i);
else
{
// go ahead and update UI if you want
NSLog(@"Finished operation %d", i);
}
}];
[self.queue addOperation:operation];
}
}
- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
[self.queue cancelAllOperations];
}
答案 1 :(得分:0)
稍后将属性设置为与块所捕获的变量设置的内容无关。如果要访问该属性,则需要访问属性:self.foo,而不是foo。
请注意,在这种情况下您仍需要小心,因为在块中捕获self会导致自我保留,这可能会导致保留周期。
(编辑) 如果你从另一个线程更新属性,这仍然是不安全的。您需要某种形式的序列化结构才能使其安全(NSLock,NSOperationQueue,dispatch_queue_t等等)。我假设这不是线程,但万一它是,这很重要。
答案 2 :(得分:-1)
试试这个:
__block __unsafe_unretained UITableView *unretTableView = self.tableview;
修改强>
我不知道您使用什么框架发布请求。但是当您使用 [myRequest postWithCompletion:yourBlock] 发布请求时,我认为还有一种方法可以更改完成块,类似 myRequest.completion = nil 。
答案 3 :(得分:-2)
插入完整性检查。
__weak UITableView *table = unretTableView;
if (table) [unretTableView reloadData];