2017-07-06 14 views
5

Như chúng ta biết chúng ta cần phải sử dụng một tham chiếu yếu bên trong một khối để phá vỡ chu kỳ giữ lại, như vậy:Sự khác nhau giữa tài liệu tham khảo yếu trong một khối và một NSTimer

__weak id weakSelf = self; 
[self doSomethingWithABlock:^() { 
    [weakSelf doAnotherThing]; 
}] 

tài liệu tham khảo Tuy nhiên yếu không thể phá vỡ giữ chu kỳ gây ra bởi một NSTimer.

__weak id weakSelf = self; 
timer = [NSTimer scheduledTimerWithTimeInterval:30.0f 
             target:weakSelf 
             selector:@selector(tick) 
             userInfo:nil 
             repeats:YES]; // No luck 

Sự khác biệt là gì? Làm thế nào bộ đếm thời gian vẫn giữ được mục tiêu?

+0

BTW, chúng ta thường sử dụng 'typeof (self)' thay vì 'id' khi định nghĩa' weakSelf'. – Rob

Trả lời

6

Toàn bộ vấn đề với kỹ thuật lựa chọn dựa trên kỹ thuật NSTimer là nó thiết lập một tham chiếu mạnh mẽ đến đối tượng bạn truyền cho nó. Vì vậy, cho dù biến bạn sử dụng để giữ tham chiếu đến mục tiêu bạn đã chuyển đến scheduledTimerWithTimeInterval là, chính nó, mạnh hay yếu, là không quan trọng. Giả sử tham chiếu target không phải là nil khi bộ hẹn giờ được lên lịch đã chọn được lập lịch, NSTimer sẽ thiết lập tham chiếu mạnh mẽ của riêng nó. Bản chất "yếu" so với "mạnh" của các tham chiếu trong mã gọi chỉ quyết định nơi ARC sẽ đặt các cuộc gọi quản lý bộ nhớ riêng trong mã của người gọi, nhưng target chỉ là một con trỏ đơn giản. đến NSTimer. Bộ chọn dựa trên NSTimer sẽ thiết lập tham chiếu mạnh mẽ của riêng nó mà không được giải quyết cho đến khi bộ hẹn giờ là invalidated.

Đây là lý do tại sao, khi chúng tôi muốn vô hiệu hóa bộ đếm thời gian được xây dựng thông qua phương pháp dựa trên công cụ chọn, chúng tôi phải có trong viewDidDisappear hoặc tương tự, thay vì dealloc.

Note, scheduledTimerWithTimeInterval bây giờ có một sự thay đổi khối dựa trên dành cho iOS 10 và sau này, vì vậy bạn có thể thưởng thức các mô hình tham khảo yếu của khối nếu bạn không cần phải hỗ trợ các phiên bản iOS trước đó:

typeof(self) __weak weakSelf = self; 
[NSTimer scheduledTimerWithTimeInterval:30 repeats:true block:^(NSTimer * _Nonnull timer) { 
    // use weakSelf here 
}]; 
Các vấn đề liên quan