Sau khi đọc Key-Value Mã hóa Programming Guide, các Key-Value Quan sát Programming Guide và mẫu Hướng dẫn đối tượng thực hiện, cũng như đọc nhiều mục StackOverflow về chủ đề này và thử nghiệm với kịch bản mô hình khác nhau, tôi cảm thấy như tôi có một nắm bắt tốt về cách mô hình dữ liệu của tôi.Các mối quan hệ "to-nhiều" có nên được mô hình hóa như là các thuộc tính không?
Tôi kết thúc bằng cách sử dụng thuộc tính được khai báo cho tất cả thuộc tính của tôi và mối quan hệ một-một, được hỗ trợ bởi các dấu hiệu riêng tư. Đối với các thuộc tính chỉ đọc cần phải được ghi riêng tư, tôi sử dụng thuộc tính readonly
trong khai báo giao diện .h
, sau đó khai báo lại thuộc tính với thuộc tính readwrite
trong tiện ích mở rộng lớp được khai báo trong tệp .m
. Bên trong các phương thức lớp, tôi luôn sử dụng các trình truy cập thuộc tính với cú pháp dấu chấm và không bao giờ truy cập trực tiếp vào các cá thể riêng tư. Tuy nhiên, có một khía cạnh vẫn khiến tôi bối rối: làm thế nào để mô hình hóa đúng mối quan hệ, đặc biệt khi bộ sưu tập được công khai bất biến, nhưng có thể thay đổi riêng tư (tức là người tiêu dùng của đối tượng mô hình không thể thêm hoặc loại bỏ các đối tượng vào). bộ sưu tập, nhưng nội dung của bộ sưu tập được quản lý riêng bởi lớp).
Tôi hiểu cách triển khai phương thức truy cập KVC cho nhiều mối quan hệ (countOf<Key>
, objectsIn<Key>AtIndex
, v.v.) và đây là tuyến đường tôi đã theo dõi từ trước tới nay.
Tuy nhiên, tôi đã thấy một số mã mẫu sử dụng các thuộc tính được khai báo để lộ các mối quan hệ, không triển khai các phương thức truy cập KVC, nhưng vẫn có thể quan sát được Khóa-giá trị. Ví dụ:
@interface MyModel : NSObject
{
// Note that the ivar is a mutable array,
// while the property is declared as an immutable array.
@private NSMutableArray *transactions_;
}
@property (nonatomic, retain, readonly) NSArray transactions;
@end
--------------------
@implementation MyModel
@synthesize transactions = transactions_;
- (void)privateMethodThatManagesTransactions
{
[[self mutableArrayValueForKey:@"transactions"] addObject:t];
}
@end
Nếu một đối tượng người tiêu dùng cho biết thêm chính nó như là một quan sát viên của một trường hợp MyModel
cho con đường quan trọng "transactions"
, nó sẽ được thông báo bất cứ khi nào giao dịch được thêm vào hoặc lấy ra từ bộ sưu tập transactions
(miễn là các đột biến là được thực hiện thông qua phương pháp mutableArrayValueForKey:
).
Với tôi, điều này có vẻ như cách sạch nhất để vạch trần các mối quan hệ với nhiều người vì tôi không cần phải viết mã bộ thu KVC và nó giữ mã sạch.
Tuy nhiên, nó dường như không phải là cách được quảng bá bởi tài liệu của Apple, và tôi không thể không tự hỏi nếu thực tế là nó hoạt động chỉ là một tác dụng phụ không đáng tin cậy. Vì vậy, trước khi cam kết với một kỹ thuật hay cách khác trong các lớp mô hình thực tế của tôi cho một dự án mà tôi bắt đầu làm việc, tôi muốn nhận được ý kiến và lời khuyên của các nhà phát triển Cocoa có kinh nghiệm. Vì vậy, câu hỏi đặt ra là: nếu tôi sử dụng các thuộc tính để mô hình hóa các mối quan hệ với nhiều mối quan hệ, tôi vẫn cần triển khai các phương thức accessor/mutator của KVC chưa? Không.
Cập nhật
Ngay cả khi tôi tuyên bố một tới nhiều tài sản như readonly
, như trong ví dụ trên, mã bên ngoài vẫn có thể gọi mutableArrayValueForKey:@"transactions"
trên đối tượng mô hình và biến đổi bộ sưu tập. Điều này dường như chỉ ra rằng việc sử dụng các thuộc tính được khai báo cho nhiều mối quan hệ không phải là cách để đi, nhưng tôi vẫn cảm thấy như tôi không hiểu ...
Tôi vừa nhận ra rằng ngay cả đối với các thuộc tính đơn giản đại diện cho thuộc tính hoặc mối quan hệ một, khai báo thuộc tính là chỉ đọc trong .H và khai báo lại nó dưới dạng ghi đè trong .M cho phép mã bên ngoài thay đổi giá trị thuộc tính bằng cách sử dụng KVC setValue: forKey: ... Vì vậy, nó có vẻ như KVC cho phép bỏ qua ngữ nghĩa thể hiện trong tuyên bố tài sản trong mọi trường hợp, vì vậy tôi đoán tôi không nên ngạc nhiên khi có thể biến đổi một bộ sưu tập chỉ đọc bằng cách sử dụng mutableArrayValueForKey: .. –