Summary: This adds a check for when developers use weakSelf (and maybe strongSelf) in a block, when there is no need for it, because it won't cause a retain cycle. In general there is an annotation in Objective-C for methods that take blocks, NS_NOESCAPE, that means that the passed block won't leave the scope, i.e. is "no escaping". So we report when weakSelf is used and the block has the annotation. Reviewed By: ngorogiannis Differential Revision: D19662468 fbshipit-source-id: f5ac695aamaster
parent
05ea5ec844
commit
63428e7b69
@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface B : NSObject
|
||||
@end
|
||||
|
||||
@interface ArrayUtils : NSObject
|
||||
|
||||
+ (void)enumerate:(void (^)(id obj, NSUInteger idx, BOOL* stop))block;
|
||||
@end
|
||||
|
||||
@interface A : NSObject
|
||||
- (NSMutableArray*)allResultsList:(NSArray<B*>*)allResults;
|
||||
|
||||
- (B*)process:(B*)obj;
|
||||
@end
|
||||
|
||||
@implementation A
|
||||
|
||||
- (B*)process:(B*)obj {
|
||||
return obj;
|
||||
}
|
||||
|
||||
- (NSMutableArray<B*>*)weak_in_noescape_block_bad:(NSArray<B*>*)allResults {
|
||||
NSMutableArray<B*>* resultsList = [[NSMutableArray<B*> alloc] init];
|
||||
__weak __typeof(self) weakSelf = self;
|
||||
[allResults enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL* stop) {
|
||||
B* result = [weakSelf process:obj]; // bug
|
||||
if (result != nil) {
|
||||
[resultsList addObject:result];
|
||||
}
|
||||
}];
|
||||
return resultsList;
|
||||
}
|
||||
|
||||
- (NSMutableArray<B*>*)weak_in_noescape_block_good:(NSArray<B*>*)allResults {
|
||||
NSMutableArray<B*>* resultsList = [[NSMutableArray<B*> alloc] init];
|
||||
[allResults enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL* stop) {
|
||||
B* result = [self process:obj]; // no bug
|
||||
if (result != nil) {
|
||||
[resultsList addObject:result];
|
||||
}
|
||||
}];
|
||||
return resultsList;
|
||||
}
|
||||
|
||||
- (NSMutableArray<B*>*)weak_in_noescape_block1_good:(NSArray<B*>*)allResults {
|
||||
NSMutableArray<B*>* resultsList = [[NSMutableArray<B*> alloc] init];
|
||||
__weak __typeof(self) weakSelf = self;
|
||||
[ArrayUtils enumerate:^(id obj, NSUInteger idx, BOOL* stop) {
|
||||
B* result = [weakSelf process:obj]; // no bug
|
||||
if (result != nil) {
|
||||
[resultsList addObject:result];
|
||||
}
|
||||
}];
|
||||
return resultsList;
|
||||
}
|
||||
|
||||
@end
|
Loading…
Reference in new issue