将字块中的块保留

我有我自己的方法,把块作为一个参数。 我想跟踪在NSDictionary内的块。 将字块添加到字典的最佳方法是什么?

我试过这个代码,但执行下面的行(setObject …)后,字典仍然是空的。 我认为这是因为该块不是NSObjecttypes。 但是,这样做的正确方法是什么?

- (void)startSomething:(NSURLRequest*)request block:(void (^)(NSURLResponse*, NSData*, NSError*))handler { NSURLConnection *connection = [NSURLConnection connectionWithRequest:request delegate:self]; [pendingRequests setObject:handler forKey:connection]; } 

编辑:

没关系。 我不知道我在想什么。 3分:

  1. 块是objc对象
  2. Typo:setObject应该是setValue
  3. forKey是一个string,所以它应该是[连接描述]或类似的东西

无论如何,我现在解决我的问题是这样的:

 - (void)startSomething:(NSURLRequest*)request block:(void (^)(NSURLResponse*, NSData*, NSError*))handler { NSURLConnection *connection = [NSURLConnection connectionWithRequest:request delegate:self]; [pendingRequests setValue:handler forKey:[connection description]]; } - (void)connectionDidFinishLoading:(NSURLConnection *)connection { dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void) { void (^handler)(NSURLResponse*, NSData*, NSError*); handler = [pendingRequests valueForKey:[connection description]]; handler(nil, nil, nil); }); } 

这仍然不起作用,或者至多只会巧合地工作。

您需要先复制handler然后再放入字典中。 就像是:

 void (^handlerCopy)(NSURLResponse*, NSData*, NSError*) = Block_copy(handler); [dict setObject:handlerCopy forKey:@"foo"]; Block_release(handlerCopy); // dict will -retain/-release, this balances the copy. 

而且,是的,它应该是setObject:forKey:objectForKey:

如果您正在使用ARC,请使用-copy

  void (^handlerCopy)(NSURLResponse*, NSData*, NSError*) = [handler copy]; [dict setObject:handlerCopy forKey:@"foo"]; 

“Typo:setObject应该是setValue”

不,你应该总是使用setObject:而不是setValue: setValue:用于键值编码,与setObject:类似setObject:对于字典(即使这样,它不是相同的,例如当键是"@something" ),而setObject:是将东西放入字典,并正确把所有types作为关键。 (顺便说一句,我不知道你想用connection作为一个关键,因为它会复制它。)

真正的问题在于,在将块存储在可能比块的原始范围更长的东西(这是块的特殊问题而不是其他对象)之前,块需要被复制,因为块(不像其他对象)最初是在栈上,因此保留它并不妨碍它被释放。 把一些东西放在字典中通常会保留,但在这种情况下还不够。

 [pendingRequests setObject:[[handler copy] autorelease] forKey:connection]; 

实际上,使用ARC,您可以简单地将块添加到NSDictionary,就像使用其他对象一样。 你不需要像Block_copy或[block copy]那样做任何特殊的事情,这样做是错误的,会导致泄漏。