Tôi đang viết một API liên quan đến xử lý sự kiện và tôi muốn có thể sử dụng các khối cho trình xử lý. Các cuộc gọi lại thường sẽ muốn truy cập hoặc sửa đổi bản thân. Trong chế độ ARC, Clang cảnh báo rằng các khối tham chiếu đến bản thân có khả năng tạo ra một chu trình giữ lại, có vẻ như một cảnh báo hữu ích mà tôi muốn tiếp tục nói chung.Vô hiệu hoá cảnh báo vòng kín vòng lặp cho các khối tự tham chiếu
Tuy nhiên, đối với phần này của API của tôi, vòng đời của cuộc gọi lại và đối tượng chứa được duy trì bên ngoài. Tôi biết tôi có thể phá vỡ chu kỳ khi đối tượng nên được deallocated.
Tôi có thể tắt cảnh báo chu kỳ lưu giữ trên cơ sở mỗi tệp với #pragma clang diagnostic ignored "-Warc-retain-cycles"
, nhưng điều đó sẽ vô hiệu hóa cảnh báo cho toàn bộ tệp. Tôi có thể bao quanh các khối với một số #pragma clang diagnostic push
và pop
xung quanh cảnh báo đó, nhưng điều đó làm cho các khối xấu xí.
Tôi cũng có thể nhận cảnh báo để biến mất bằng cách tham chiếu biến __weak trỏ đến tự thay vì tự tham chiếu trực tiếp, nhưng điều đó làm cho các khối khó sử dụng hơn.
Giải pháp tốt nhất mà tôi đã đưa ra là macro này mà không được vô hiệu chẩn đoán xung quanh khối:
#define OBSERVE(OBJ, OBSERVEE, PATH, CODE) \
[(OBJ) observeObject:(OBSERVEE) forKeyPath:(PATH) withBlock:^(id obj, NSDictionary *change) { \
_Pragma("clang diagnostic push") \
_Pragma("clang diagnostic ignored \"-Warc-retain-cycles\"") \
do { CODE; } while(0); \
_Pragma("clang diagnostic pop") \
}];
đó làm việc, nhưng nó không phải là rất có thể phát hiện cho người dùng API, nó không cho phép lồng nhau các nhà quan sát, và nó tương tác kém với trình soạn thảo của XCode. Có cách nào tốt hơn để vô hiệu hóa hoặc tránh cảnh báo?
Tạo tham chiếu '__weak' thành' self' theo nghĩa đen có một dòng mã. Tôi nghĩ rằng sửa chữa vấn đề trong trường hợp này là tốt hơn so với cố gắng để làm giảm bớt các triệu chứng. Làm thế nào để tham chiếu đến 'weakSelf' thay vì' self' làm cho khối dễ chịu hơn để sử dụng? –
Nó ít dễ chịu hơn theo một vài cách. Những người nghe thường khá ngắn, đôi khi là một phát biểu duy nhất. Khai báo __weak tăng gấp đôi kích thước của người nghe. Nó cũng có nghĩa là bạn cần phải đủ điều kiện truy cập tài sản hơn là sử dụng một suy luận tự. Tôi sẽ đồng ý rằng giải pháp hiện tại của tôi có lẽ tệ hơn là chỉ sử dụng __weak, nhưng tôi đã hy vọng có được một giải pháp tốt hơn thông qua câu hỏi này. –
Bạn có thể thay đổi nguyên mẫu của khối hoàn thành của mình để chấp nhận đối số "tự" không? Bây giờ mã mà bạn vượt qua các khối của bạn sẽ trông giống nhau (ngoại trừ chấp nhận một đối số thêm) và bạn có thể loại bỏ các cảnh báo. (ví dụ: API của bạn cũng truyền đối tượng được đề cập đến khối của bạn) – nielsbot