9

Đó là một mô hình phổ biến trong mã của tôi để phân bổ một đối tượng, để cho nó làm một số công cụ với một handler hoàn thành và phát hành nó trong xử lý:Làm cách nào để phát hành một đối tượng có trình xử lý hoàn thành khối trong ARC?

LongOperation *foo = [[LongOperation alloc] init]; 
[foo runWithCompletion:^{ 
    // run some code and then: 
    [foo autorelease]; 
}]; 

này hoạt động khá tốt, nhưng khi tôi cố gắng để chuyển đổi mã cho ARC, Xcode đúng phàn nàn rằng nó không thể chỉ đơn giản là thả các autorelease từ khối, vì điều đó sẽ làm cho đối tượng foo được deallocated sau khi rời khỏi phạm vi.

Vậy cách tốt nhất để viết loại mẫu này trong ARC là gì? Tôi có thể giới thiệu một biến Ví dụ cho foo:

[self setFoo:[[LongOperation alloc] init]]; 
[foo runWithCompletion:^{ 
    // run some code and then: 
    [self setFoo:nil]; 
}]; 

... nhưng mã sẽ không được tái ký dự thi nữa.

Trả lời

4

Trong hầu hết các trường hợp, nó sẽ hoạt động (tức là, nếu bất cứ điều gì tham chiếu tự bên trong foo, foo sẽ kéo dài đủ để đáp ứng mã đó trước khi biến mất). Nếu có những vấn đề với sự tham khảo yếu và rằng foo như vậy có vẻ như nó sẽ biến mất nhưng không nên cho đến sau khi xử lý chạy, bạn có thể làm điều gì đó như:

__block LongOperation* foo = [[LongOperation alloc] init]; 
[foo runWithCompletion:^{ 
    // do some things 
    foo = nil; 
}]; 

Lưu ý đây là loại trái ngược với mô hình này gây ra đối tượng/không/được chụp trong các quy tắc bộ nhớ được quản lý.

+0

Điều này không trả lời câu hỏi là phải làm gì khi ngữ cảnh chứa foo biến mất lâu rồi. Với giải pháp này, khung ngăn xếp gọi [foo runWithCompletion:] phải chặn cho đến khi chạy xong hoặc có nguy cơ một người đập bể ngăn xếp. –

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