2015-07-22 19 views
8

Tôi đã đọc rằng khi một khối như thế này được thực hiện:weakSelf (tốt), strongSelf (xấu) và các khối (xấu xí)

__weak typeof(self) weakSelf = self; 
[self doSomethingInBackgroundWithBlock:^{ 
     [weakSelf doSomethingInBlock]; 
     // weakSelf could possibly be nil before reaching this point 
     [weakSelf doSomethingElseInBlock]; 
}]; 

nó nên được thực hiện theo cách này:

__weak typeof(self) weakSelf = self; 
[self doSomethingInBackgroundWithBlock:^{ 
    __strong typeof(weakSelf) strongSelf = weakSelf; 
    if (strongSelf) { 
     [strongSelf doSomethingInBlock]; 
     [strongSelf doSomethingElseInBlock]; 
    } 
}]; 

Vì vậy, tôi muốn nhân rộng một tình huống mà weakSelf nhận được nil ở giữa một khối thực hiện.

Vì vậy, tôi đã tạo ra đoạn mã sau:

* 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 

Vì vậy, tôi đã mong rằng createBlockWeakyfy sẽ tạo ra các kịch bản Tôi muốn tái tạo nhưng tôi không thể làm được.

Kết quả là như nhau cho createBlockWeakyfy và createBlockStrongify

HELLO!!! 
Block container reference set to nil 
BYE!!! 
Block Container Ey I have been dealloc! 

Ai đó có thể cho tôi biết những gì tôi đang làm sai?

+0

Thử thêm '[[NSGarbageCollector defaultCollector] collectIfNeeded];' sau khi bạn đặt nó thành 0 để buộc GC. Có thể hoặc không thể làm bất cứ điều gì. –

+0

Có thể liên quan ... http://stackoverflow.com/questions/24093802/objective-c-block-lifetime-arc – CrimsonChris

Trả lời

3

Khối dispatch_async của bạn là việc tạo tham chiếu mạnh mẽ. Khi khối đó truy cập vào số MyBlockContainer của bạn để nhận thuộc tính myBlock, nó tạo một tham chiếu mạnh mẽ cho thuộc tính đó trong suốt vòng đời đó.

Nếu bạn thay đổi mã của bạn như thế này:

__weak void (^block)() = self.blockContainer.myBlock; 

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 
    block(); 
}); 

Bạn sẽ thấy kết quả mà bạn đang mong đợi.

+0

Cảm ơn bạn đã trả lời! – agy

Các vấn đề liên quan