Вы фактически не выделяете блок в этом коде.Тело блока - все статическое содержание;после компиляции ничего не изменится.
Если вы сделаете это:
_weakBlock = ^void{
NSLog(@"Execution inside a weakBlock");
};
NSLog(@"%@", [_weakBlock class]);
Вы увидите это:
2018-10-21 09:33:48.827423-0500 kdkdkdkds[9367:1777827] __NSGlobalBlock__
Компилятор распознал, что блок ничего не захватываетэто может измениться во время выполнения и, соответственно, создать глобальный статический блок, который никогда не будет выделен.
Как сказал @Brandon в комментарии, если вы объявили локальную переменную в своей области и вызвали блок стекавыделено, что не уйдет до конца объема.
@autoreleasepool {
void __weak (^_weakBlock)(void);
int k = 2;
_weakBlock = ^void{
NSLog(@"Execution inside a weakBlock (%d)", k);
};
NSLog(@"C; %@", [_weakBlock class]);
NSLog(@"P; %p", _weakBlock);
}
2018-10-21 09:36:31.585458-0500 kdkdkdkds[9392:1780803] C; __NSStackBlock__
2018-10-21 09:36:31.586291-0500 kdkdkdkds[9392:1780803] P; 0x7ffeefbff4c0
Теперь назначение переменной экземпляра немного меняет правила, поскольку вы назначаете вне области действия.
@interface SpongeBob:NSObject
@end
@interface SpongeBob ()
{
}
@property (nonatomic, weak) void (^weakBlock)(void);
@end
@implementation SpongeBob
- (instancetype)init
{
self = [super init];
if (self) {
int k = 2;
_weakBlock = ^void{
NSLog(@"Execution inside a weakBlock (%d)", k);
};
NSLog(@"C; %@", [_weakBlock class]);
NSLog(@"P; %p", _weakBlock);
}
return self;
}
@end
int main(int argc, const char * argv[]) {
@autoreleasepool {
[[SpongeBob alloc] init];
}
return 0;
}
2018-10-21 09:43:39.518545-0500 kdkdkdkds[9480:1787889] C; __NSStackBlock__
2018-10-21 09:43:39.518883-0500 kdkdkdkds[9480:1787889] P; 0x7ffeefbff488
Подождите.Какие?Если это значение действительно присваивается ивару, то это бомба замедленного действия.Итак, давайте попробуем кое-что:
Если мы добавим:
- (void)squarePants
{
NSLog(@"C; %@", [_weakBlock class]);
NSLog(@"P; %p", _weakBlock);
}
И затем назовем это:
SpongeBob *bob = [[SpongeBob alloc] init];
[bob squarePants];
Это происходит сбой, как и ожидалось, потому что блок стекабольше не действительны как init
область
(Это кажется довольно значительным. С другой стороны, если вы устраните предупреждение, сбой исчезнет.)
Теперь, если вы скопируете блокпри назначении, затем немедленное освобождение при назначении делает вкл:
_weakBlock = [^void{
NSLog(@"Execution inside a weakBlock (%d)", k);
} copy];
2018-10-21 09:48:04.295762-0500 kdkdkdkds[9510:1792549] C; (null)
2018-10-21 09:48:04.296167-0500 kdkdkdkds[9510:1792549] P; 0x0