4

In this answer: Can I pass a block as a @selector with Objective-C?

Lemnar says you could do this:

id block = [^{NSLog(@"Hello, world");} copy];// Don't forget to -release.

[button addTarget:block
           action:@selector(invoke)
 forControlEvents:UIControlEventTouchUpInside];

Where exactly should it be released? Where I'd like to use it, is in the viewDidLoad method, so viewDidUnload seems like the place to release it, but is there any way to release it without creating an ivar?

Community
  • 1
  • 1
Jonathan.
  • 53,997
  • 54
  • 186
  • 290

2 Answers2

8

That isn't supported; the invoke method is not public and Blocks are not intended to be used in such a role directly.

File an enhancement request and, as a workaround, use objc_implementationWithBlock() and (IIRC) class_addMethod() to create a block-as-method that will work in target action.

bbum
  • 162,346
  • 23
  • 271
  • 359
2

Something has to take ownership of that block object for it to stick around. Ownership in Objective-C means having a reference to the owned object, and a reference count ("retain"). You won't be able to release it without a reference to it -- that means a leak. You need a variable somewhere that points to the object. The button would itself be a good candidate for owning its target, but UIButtons don't work that way. I suppose you could subclass UIButton, possibly; otherwise, yes, you'll need to create an ivar in one of your controllers.

jscs
  • 63,694
  • 13
  • 151
  • 195