Ich habe gelesen, dass, wenn ein Block wie folgt ausgeführt:weakSelf (das gute), strongSelf (das schlechte) und Blöcke (die hässliche)
__weak typeof(self) weakSelf = self;
[self doSomethingInBackgroundWithBlock:^{
[weakSelf doSomethingInBlock];
// weakSelf could possibly be nil before reaching this point
[weakSelf doSomethingElseInBlock];
}];
es sollte auf diese Weise geschehen:
__weak typeof(self) weakSelf = self;
[self doSomethingInBackgroundWithBlock:^{
__strong typeof(weakSelf) strongSelf = weakSelf;
if (strongSelf) {
[strongSelf doSomethingInBlock];
[strongSelf doSomethingElseInBlock];
}
}];
Also ich möchte eine Situation replizieren, in der weakSelf mitten in einer Blockausführung Null bekommt.
So habe ich den folgenden Code erstellt:
* Viewcontroller *
@interface ViewController()
@property (strong, nonatomic) MyBlockContainer* blockContainer;
@end
@implementation ViewController
- (IBAction)caseB:(id)sender {
self.blockContainer = [[MyBlockContainer alloc] init];
[self.blockContainer createBlockWeakyfy];
[self performBlock];
}
- (IBAction)caseC:(id)sender {
self.blockContainer = [[MyBlockContainer alloc] init];
[self.blockContainer createBlockStrongify];
[self performBlock];
}
- (void) performBlock{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
self.blockContainer.myBlock();
});
[NSThread sleepForTimeInterval:1.0f];
self.blockContainer = nil;
NSLog(@"Block container reference set to nil");
}
@end
* MyBlockContainer *
@interface MyBlockContainer : NSObject
@property (strong) void(^myBlock)();
- (void) createBlockWeakyfy;
- (void) createBlockStrongify;
@end
@implementation MyBlockContainer
- (void) dealloc{
NSLog(@"Block Container Ey I have been dealloc!");
}
- (void) createBlockWeakyfy{
__weak __typeof__(self) weakSelf = self;
[self setMyBlock:^() {
[weakSelf sayHello];
[NSThread sleepForTimeInterval:5.0f];
[weakSelf sayGoodbye];
}];
}
- (void) createBlockStrongify{
__weak __typeof__(self) weakSelf = self;
[self setMyBlock:^() {
__typeof__(self) strongSelf = weakSelf;
if (strongSelf){
[strongSelf sayHello];
[NSThread sleepForTimeInterval:5.0f];
[strongSelf sayGoodbye];
}
}];
}
- (void) sayHello{
NSLog(@"HELLO!!!");
}
- (void) sayGoodbye{
NSLog(@"BYE!!!");
}
@end
Damit ich erwartete createBlockWeakyfy das Szenario generieren Ich wollte replizieren, aber ich habe es nicht geschafft.
Der Ausgang ist für createBlockWeakyfy und createBlockStrongify
HELLO!!!
Block container reference set to nil
BYE!!!
Block Container Ey I have been dealloc!
Jemand kann mir sagen, was ich falsch mache?
Versuchen Sie, '[[NSGarbageCollector defaultCollector] collectIfNeeded];' hinzuzufügen, nachdem Sie es auf null gesetzt haben, um den GC zu erzwingen. Macht oder macht vielleicht gar nichts. –
Möglicherweise verwandt ... http://stackoverflow.com/questions/24093802/objective-c-block-lifetime-arc – CrimsonChris