Skip to content

Instantly share code, notes, and snippets.

@jspahrsummers
Last active September 26, 2019 05:24
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save jspahrsummers/5780224 to your computer and use it in GitHub Desktop.
Save jspahrsummers/5780224 to your computer and use it in GitHub Desktop.
Untested proof of concept for a better @weakify macro.
#define $(...) \
({ \
__weak __typeof__(self) weakSelf = self; \
\
^(__VA_ARGS__) { \
__strong __typeof__(weakSelf) self = weakSelf; \
$_body_
#define $_body_(...) \
__VA_ARGS__ \
}; \
})
$(id arg1, unsigned arg2)({
[self doSomething:arg1 withInterestingValue:arg2];
});
@robrix
Copy link

robrix commented Jun 14, 2013

Ah, cute approach with the block there. Hadn’t considered that.

My hack was this:

#define weakify(symbol, block) (^{ \
  __weak __typeof__(symbol) weakSelf = symbol; \
  return ^{ \
    __typeof__(symbol) symbol = weakSelf; \
    return block(); \
  }; \
}())

weakify(self, ^{ [self mementoMori]; })

@jspahrsummers
Copy link
Author

@robrix That block argument will definitely get lexed wrong in many cases. Using a variadic macro that actually accepts only the block will work around that issue (since the arguments will be spliced back together).

@robrix
Copy link

robrix commented Jun 14, 2013

Fixed:

#define weakify(symbol, args, ...) \
    (^{ \
        __weak __typeof__(symbol) weakSelf = symbol; \
        return ^args{ \
            __typeof__(symbol) symbol = weakSelf; \
            return __VA_ARGS__(); \
        }; \
    }())

weakify(self, (id object, BOOL *stop), ^{ [self mementoMori]; })

This lexes correctly, but I haven’t yet verified whether it avoids the retain cycle correctly (I can’t imagine why it wouldn’t). And it mercifully avoids having to redeclare the arguments, at the cost of being a little weird.

Unfortunately it can only be used for a single symbol; forcing motivated clients to parenthesize their blocks might lift that restriction, but it’s annoying pulling args off the end of varargs macros and I am tired.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment