Keep blocks inside a dictionary

吃可爱长大的小学妹 提交于 2019-11-28 20:42:34

That still isn't going to work or, at best, will only work coincidentally.

You need to copy the handler before shoving it in the dictionary. Something like:

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

And, yes, it should be setObject:forKey: and objectForKey:.

If you are using ARC, use -copy:

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

"Typo: setObject should be setValue"

NO, you should always use setObject: instead of setValue:. setValue: is for key-value coding and coincidentally works similar to setObject: for a dictionary (even then, it's not the same, e.g. when the key is "@something"), while setObject: is the correct method for putting things in a dictionary, and which correctly takes all types as keys. (By the way I'm not sure you want to use connection as a key since it will copy it.)

The real problem is that blocks need to be copied before you store them away in something that might last longer than the original scope of the block (this is a special issue for blocks and not for other objects), since blocks (unlike other objects) are initially on the stack, and thus retaining it does not prevent it from becoming deallocated. Putting something in a dictionary normally retains it, but that is not enough in this case.

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

Actually with ARC you can simply add the block to the NSDictionary as you would with any other object. You do not need to do anything special like Block_copy or [block copy], and doing that would be wrong and will cause a leak.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!