I've got a solution for this that I don't especially like, but it might provoke a better answer. I'll leave this unanswered in the hope of a better solution arriving.
Here's one way to do it:
// Here's a method definition…
-(void) aMethod
{
// Want to create a block in which its impossible to refer to strong "self".
// Begin a new scope to do this in.
{
// Within this scope, cover the existing "self" with a weak variant.
__weak STWeatherTableViewController const *weakSelf = self;
__weak STWeatherTableViewController const *self = weakSelf;
// Sadly it's _not_ possible to simply do:
// __weak STWeatherTableViewController const *self = self;
// … it gives a warning about initialisation of a variable form its own
// uninitialised value, which makes sense, though you might hope the
// compiler would work out what's going on.
// Make a block that captures the covered self and does something with it.
void (^exampleBlock)() = ^(){ [self lineHeight]; };
exampleBlock();
}
// Now, back in the scope of the original method, "self" is non weak
// again.
[self doSomething];
}
I guess, if you really cared a lot about this, you could use a macro. It would at least abstract the idea and make uses easy to find and notice in code:
#define WEAKEN_SELF(classType) \
__weak classType const *weakSelf = self; \
__weak classType const *self = weakSelf
Or even:
#define WEAKEN_SELF(classType) \
__weak classType const *weakSelfTemporary##__LINE__ = self; __weak classType const *self = weakSelfTemporary##__LINE__;
Which you'd use it like this:
-(void) testMethod
{
// You still need that scope or you cover the original "self".
{
WEAKEN_SELF(STWeatherTableViewController)
void (^exampleBlock)() = ^(){ [self someMethodOrOther]; };
exampleBlock();
}
}
I'm unconvinced it is worth the effort though. Having the compiler warnings is probably good enough and they can presumably be turned in to errors?