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