4

Here's an interesting one for the objective-C gurus out there...

Is there a way to declare an objective-C block typedef that contains an argument of that typedef?

typedef BOOL (^SSCellAction) ( UITableViewController* inTVC, SSCellAction inChainedAction );

The idea is that I wanted to used chained menu action system that allows a chain of work/response to occur (usually 1-3 items). When the last action invokes, it passes nil for inChainedAction. Since this seems relatively trivial to imagine, I'll be dammed if I can't figure out how to declare it without llvm saying no. :)

Drew O'Meara
  • 401
  • 2
  • 14
  • I think you should just have a second typedef for the continuation that has the same arguments. – i_am_jorf Nov 22 '14 at 19:02
  • How would you do that @jeffamaphone ? – nhgrif Nov 22 '14 at 19:12
  • Ah, yeah. Nevermind. – i_am_jorf Nov 22 '14 at 19:38
  • 1
    It's unlikely that this is possible. It's essentially the same issue in C as trying to `typedef` a function that has same function as itself for a parameter. For example, see http://stackoverflow.com/questions/793449/recursive-declaration-of-function-pointer-in-c and related questions. – rmaddy Nov 22 '14 at 20:04
  • Like adding an array into itself I think this can cause serious problems in memory management. – Rob Sanders Nov 22 '14 at 20:10
  • Well, a counter analogy is that a struct can contain a ptr of the same type because the nature of a struct ptr is still just a ptr. Likewise, a specific block typedef is still a block typedef. For example, a blind ref could be passed in and then internally/privately reform into its original type, complete with all its properties. @maddy – Drew O'Meara Nov 22 '14 at 21:38
  • @RASS This issue is nothing like adding an array to itself (which can be done without any issues). – rmaddy Nov 29 '14 at 18:44

1 Answers1

2

rmaddy's comment is correct. Just as in C, a typedef cannot use itself. Basically, a typedef does not make a real type, but just makes an alias that the compiler expands out at compile-time. It is always possible to manually expand all typedefs in your program yourself (which is sometimes an instructive exercise), so that your program is written without typedefs. However, a recursive typedef cannot be expanded.

Some possible workarounds:

  • Use id as the parameter type, and cast back into the right type inside the block. This loses type safety.
  • Or, use a struct type of one member, the block. A struct is a real type, so it can be used within its definition. The downside of this is that you explicitly "wrap" the block into the struct type to pass it, and explicitly "unwrap" the struct into the block by accessing the field when you need to call it. This way is type-safe.
newacct
  • 119,665
  • 29
  • 163
  • 224
  • sounds like two great ways the objC processor could insert to expand acceptance in order to support the original goal. it'd be great to hear from an objC dev in detail. i'm curious if it can or can't be added in the future if we agree that @newacct's deterministic workarounds are correct. – Drew O'Meara Nov 23 '14 at 04:52
  • @DrewO'Meara: I think it's possible to add an extension to C to support recursive function or block typedefs. It wouldn't have to do with Objective-C specifically. But I don't think anyone plans on doing that. – newacct Nov 23 '14 at 06:58