Tôi biết rằng OBJC_ASSOCIATION_ASSIGN tồn tại, nhưng nó có không tham chiếu nếu đối tượng đích được dealloced? Hoặc là nó giống như những ngày cũ mà tham chiếu cần phải nhận được nil-ed hoặc chúng tôi có nguy cơ một truy cập xấu sau này?Sử dụng objc_setAssociatedObject với tham chiếu yếu
Trả lời
Sau khi dùng thử, câu trả lời là KHÔNG.
Tôi chạy đoạn mã sau dưới iOS 6 Simulator, nhưng nó có lẽ sẽ có hành vi tương tự với dòng máy trước của runtime:
NSObject *test1 = [NSObject new];
NSObject __weak *test2 = test1;
objc_setAssociatedObject(self, "test", test1, OBJC_ASSOCIATION_ASSIGN);
test1 = nil;
id test3 = objc_getAssociatedObject(self, "test");
Trong phần cuối, test1 và test2 là con số không, và Test3 là con trỏ được lưu trước đó vào test1. Sử dụng test3 sẽ dẫn đến việc truy cập một đối tượng đã được dealloced.
Typo trong đó? "test1" liên quan đến "test" và "test2" như thế nào? – Jeff
Hành vi này không được chỉ định trong tài liệu hoặc tiêu đề là tốt nhất mà tôi có thể biết, vì vậy có thể là chi tiết triển khai mà bạn không nên đếm, ngay cả khi bạn có thể phân biệt hành vi hiện tại là gì. Tôi đoán rằng đó là không phải là được xóa. Đây là lý do:
Nói chung, không cần phải tham khảo nil
tham chiếu trong iVars trong thời gian -dealloc
. Nếu một đối tượng được dealloced, nó sẽ không quan trọng nếu iVars của nó đã được zeroed ra, bởi vì bất kỳ tiếp tục truy cập của đối tượng dealloced hoặc iVars của nó là, trong và của chính nó, một lỗi lập trình. Trong thực tế, tôi đã nghe một số người cho rằng tốt hơn là không phải là xóa tham chiếu trong thời gian -dealloc
, bởi vì nó sẽ làm cho truy cập sai hơn hiển thị/phơi bày lỗi sớm hơn.
EDIT: Ồ, tôi đoán tôi đã đọc sai câu hỏi của bạn. Bạn muốn "zeroing references". Bộ nhớ được liên kết không xuất hiện để hỗ trợ những bộ nhớ đó. Bạn có thể tạo một lớp pass-through tầm thường với một ivar/property được đánh dấu là __weak và đạt được hiệu ứng tương tự như vậy. Một chút kludgey, nhưng nó hoạt động.
Tôi có nghĩa là trong trường hợp tôi đang xem xét, nó không phải là một sai lầm nếu tôi cố gắng truy cập vào các đối tượng sau khi nó dealloced. Nếu tôi có một tài liệu tham khảo yếu, giống như một tham chiếu đến một đại biểu, tôi hy vọng rằng nó có thể không tồn tại nữa bởi thời gian tôi nhắn tin cho nó. – ultramiraculous
Như được chứng minh tối đa, OBJC_ASSOCIATION_ASSIGN
không làm tham chiếu yếu zeroing và bạn có nguy cơ truy cập vào đối tượng được phân bổ. Nhưng khá dễ thực hiện bản thân. Bạn chỉ cần một lớp đơn giản để quấn một đối tượng với một tham chiếu yếu:
@interface WeakObjectContainer : NSObject
@property (nonatomic, readonly, weak) id object;
@end
@implementation WeakObjectContainer
- (instancetype) initWithObject:(id)object
{
if (!(self = [super init]))
return nil;
_object = object;
return self;
}
@end
Sau đó, bạn phải kết hợp WeakObjectContainer
như OBJC_ASSOCIATION_RETAIN (_NONATOMIC):
objc_setAssociatedObject(self, &MyKey, [[WeakObjectContainer alloc] initWithObject:object], OBJC_ASSOCIATION_RETAIN_NONATOMIC);
và sử dụng object
tài sản để truy cập nó trong để có được một tài liệu tham khảo yếu zeroing:
id object = [objc_getAssociatedObject(self, &MyKey) object];
Hehe! Cách tiếp cận thực sự thông minh. Yêu nó! Tôi sẽ ghi nhớ điều đó. – MonsieurDart
Tại sao không chỉ sử dụng NSValue :: valueWithNonretainedObject:? – AlexDenisov
Vì '- [NSValue nonretainedObjectValue]' không trả về một đối tượng * yếu * và do đó không làm tham chiếu yếu zeroing. – 0xced
một lựa chọn hơn tương tự như WeakObjectContainer
:
- (id)weakObject {
id (^block)() = objc_getAssociatedObject(self, @selector(weakObject));
return (block ? block() : nil);
}
- (void)setWeakObject:(id)object {
id __weak weakObject = object;
id (^block)() = ^{ return weakObject; };
objc_setAssociatedObject(self, @selector(weakObject),
block, OBJC_ASSOCIATION_COPY);
}
- 1. Khi nào sử dụng các tham chiếu yếu trong Python?
- 2. Java: Ngăn xếp với tham chiếu yếu
- 3. Tham chiếu yếu trong clojure
- 4. Sự khác nhau giữa tham chiếu yếu và tham chiếu yếu kém là gì?
- 5. Tham chiếu yếu với điều kiện/thời gian chờ
- 6. Tham chiếu yếu bên trong một khối
- 7. Không tham chiếu yếu trong ARC
- 8. Các lợi ích tham chiếu yếu
- 9. Sử dụng tham chiếu làm loại mẫu
- 10. Các tham chiếu yếu được triển khai như thế nào?
- 11. iVars tham chiếu mạnh mẽ, yếu hoặc gì?
- 12. Tạo một tham chiếu yếu cho một đối tượng
- 13. Trình nghe ẩn danh có tương thích với các tham chiếu yếu không?
- 14. Sự kiện trong ViewModel với System.Windows.Interactivity.EventTrigger, có tham chiếu yếu không?
- 15. Mục đích của việc sử dụng tham chiếu đến tham chiếu trong C++ là gì?
- 16. Đang sử dụng Assembly.Load tham chiếu tĩnh hoặc tham chiếu động?
- 17. objc_setAssociatedObject không có trong iOS?
- 18. Làm cách nào để thay thế các tham chiếu yếu khi sử dụng ARC và nhắm mục tiêu iOS 4.0?
- 19. Làm cách nào để buộc R sử dụng mức yếu tố được chỉ định làm tham chiếu trong hồi quy?
- 20. Sử dụng tham chiếu Rvalue trong danh sách khởi tạo
- 21. Thêm tham chiếu thêm tham chiếu sai
- 22. iOS - Không thể sử dụng 'siêu' làm tham chiếu?
- 23. Cách sử dụng xpointer với Xinclude để tham chiếu các phần tử
- 24. Tham chiếu rvalue cho const có sử dụng không?
- 25. Sử dụng ndb.KeyProperty cách tham chiếu cùng một mô hình?
- 26. Sử dụng chuỗi để tham chiếu đến tên đối tượng
- 27. ASP.NET - Sử dụng ScriptManager trong tham chiếu thư viện lớp
- 28. Java: Sử dụng enum làm tham chiếu mảng
- 29. Sử dụng tham chiếu làm id trong fluentnhibernate
- 30. Nhập và tham chiếu bắt buộc để sử dụng LINQ
Vâng, đúng vậy. Tôi se thử no. – ultramiraculous