Trong nhiệm vụ cập nhật mô hình Dữ liệu cốt lõi trong dự án iOS của tôi, tôi đang truy vấn máy chủ cho các đối tượng JSON tương ứng - ở một mức độ nào đó - với các thực thể được quản lý của mô hình của tôi. Kết quả cuối cùng mà tôi đang phấn đấu là một giải pháp cập nhật đáng tin cậy từ đầu ra JSON.Làm cách nào để kiểm tra sự tồn tại và loại thuộc tính dựa trên khóa nhập NSString?
Đối với các ví dụ trong câu hỏi này, tôi sẽ đặt tên cho đối tượng được quản lý dữ liệu lõi existingObj
và từ điển JSON deserialized đến updateDict
. Phần khó khăn là đối phó với những sự kiện này:
- Không phải tất cả các thuộc tính của
existingObj
có mặt trongupdateDict
- Không phải tất cả các thuộc tính của
updateDict
có sẵn trongextistingObj
. - Không phải tất cả các loại thuộc tính của
existingObj
đều khớp với thuộc tính được deserialized JSON. (một số chuỗi có thể cần một wrapper Objective-C tùy chỉnh). updateDict
có thể chứa các giá trị cho các khóa chưa được khởi tạo (nil
) trongexistingObj
.
Điều này có nghĩa là trong khi lặp qua các từ điển được cập nhật, phải có một số kiểm tra thuộc tính qua lại. Trước tiên tôi phải kiểm tra xem các thuộc tính của updateDict
tồn tại trong existingObj
, sau đó tôi thiết lập giá trị sử dụng KVC, như vậy:
// key is an NSString, e.g. @"displayName"
if ([existingObj respondsToSelector:NSSelectorFromString(key)) {
[existingObj setValue:[updateDict objectForKey:key] forKey:key];
}
Mặc dù phần này tác phẩm, tôi không thích thực tế rằng tôi thực sự thử nghiệm cho displayName
như là một getter, trong khi tôi về để gọi setDisplayName:
setter (gián tiếp thông qua KVC). Những gì tôi muốn là một cái gì đó như [currentObj
hasWritablePropertyWithName
: key], nhưng một cái gì đó mà tôi không thể tìm thấy.
Điều này làm cho truy vấn con A: Làm thế nào để kiểm tra cho trình thiết lập thuộc tính, nếu bạn chỉ có tên của thuộc tính?
Phần tiếp theo là nơi tôi muốn tự động nhận dạng thuộc tính dựa trên loại của chúng. Nếu cả hai số updateDict
và existingObj
đều có NSString cho khóa @ "displayName", việc đặt giá trị mới rất dễ dàng. Tuy nhiên, nếu updateDict
chứa một NSString cho khóa @ "color" đó là @ "niceShadeOfGreen", tôi muốn biến điều này thành phiên bản UIColor phù hợp. Nhưng làm cách nào để kiểm tra loại thuộc tính nhận trong số existingObj
để tôi biết khi nào nên chuyển đổi giá trị và thời điểm chỉ định đơn giản? Tôi đã hy vọng cho một cái gì đó dọc theo dòng của
typeOfSelector:
if ([existingObj typeOfSelector:sel] == [[updateDict objectForKey:key] class]) {
// regular assignment
} else {
// perform custom assignment
}
Tất nhiên đây là boguscode. Tôi không thể dựa vào thử nghiệm loại giá trị của existingObj
-property, vì nó có thể được đơn lẻ hóa hoặc nil
.
Câu hỏi con B: Làm cách nào để kiểm tra loại thuộc tính, nếu bạn chỉ có tên của thuộc tính?
Tôi đoán là vậy. Tôi nhận ra đây phải là một sự lừa đảo của thứ gì đó đã có ở đây, nhưng tôi không thể tìm thấy nó. Có lẽ các bạn có thể?
Chúc mừng, EP.
P.S. Nếu bạn có một cách tốt hơn để đồng bộ hóa các đối tượng Objective-C tùy chỉnh với các đối tượng JSON được deserialized, hãy chia sẻ! Cuối cùng, kết quả là những gì đếm.
Tôi đề nghị bạn chỉ cần truy vấn 'updateDict' cho các phím * bạn biết * và bỏ qua tất cả phần còn lại. – Costique
Từ ví dụ trên, đó thực sự là một lựa chọn khả thi. Tuy nhiên trong kịch bản thế giới thực, điều này sẽ làm thay đổi đối tượng được quản lý và cập nhật rất phức tạp. Các đối tượng bao gồm hơn 30 khóa/thuộc tính, hầu hết trong số đó là NSString hoặc NSNumber. Nếu có một giải pháp cho câu hỏi trên, việc đồng bộ sẽ không cần sửa đổi khi các kiểu nguyên thủy được thêm vào hoặc sửa đổi ở cả hai bên. – epologee