2009-08-07 40 views
12

Tôi muốn lưu trữ một số giá trị bằng cách sử dụng NSNull và sau đó tuần tự hóa dữ liệu này bằng danh sách thuộc tính. Sự cố là NSNull không được phép và tôi nhận được lỗi "Danh sách thuộc tính có định dạng không hợp lệ". Có một cách giải quyết cho điều này? Có vẻ rất ngạc nhiên khi họ không đặt NSNull vào danh sách các đối tượng plist hợp lệ.Làm thế nào để sắp xếp một danh sách NSDictionary/NSArray/Property (plist) chứa NSNull

+0

Câu trả lời được cung cấp bởi Saurabh Wadhwa hoạt động giống tuyệt vời, tôi chỉ sử dụng nó bản thân mình, quá xấu các poster ban đầu không phải là xung quanh để chấp nhận nó ... –

Trả lời

5

Không, không có cách nào để đặt NSNull trong danh sách thuộc tính. (Câu đố: định dạng danh sách thuộc tính nhị phân thực sự hỗ trợ null, nhưng người viết không thực hiện hỗ trợ.)

Để giải quyết một cách dễ dàng nhất, đơn giản là lọc ra các giá trị rỗng, vì vậy {foo = "bar"; baz = null; } trở thành {foo = "bar"; }.

+0

của nó không chính xác những điều tương tự như tôi cần các giá trị null để chỉ ra rằng khóa tồn tại nhưng không có giá trị tương ứng (tức là tôi đã biết có một khóa không có dữ liệu như trái ngược với một khóa mới mà tôi không biết). –

+0

Có lẽ bạn có thể nối tiếp cả A) một từ điển chỉ với các khóa có giá trị tương ứng và B) một mảng của tất cả các khóa đã biết, bất kể chúng có đính kèm dữ liệu hay không. Cuối cùng không có cách nào để đưa NSNull vào một plist trực tiếp, do đó bạn cần phải tìm một cách giải quyết. –

3

Từ các tài liệu của NSPropertyListSerializationClass:

Một đối tượng danh sách bất động sản. plist phải là một loại đối tượng NSData, NSString, NSNumber, NSDate, NSArray hoặc NSDictionary . Các đối tượng vùng chứa cũng phải là chỉ chứa các loại đối tượng này.

Vì vậy, bạn cần có một trong số đó. Tùy thuộc vào loại dữ liệu, bạn có thể đặt trong trình giữ chỗ thay vì NSNull và sau đó thực hiện một quy trình trước/sau khi tải .plist (ví dụ, sử dụng đối tượng NSData có độ dài bằng không để đại diện cho NSNull của bạn trong plist). Chính xác loại trình giữ chỗ nào sẽ phụ thuộc vào loại dữ liệu bạn đang lưu trữ và chọn thứ gì đó cần tránh. Sau đó, sau khi tải, dịch NSData trống trở về NSNull.

+0

Nghiêm túc những gì là sai với các lập trình viên táo ??? Tôi ghét phải viết mã như thế. –

+3

DD, nếu những gì bạn muốn là serialization chung, sử dụng NSCoder. Danh sách thuộc tính có một số loại cố định, vì vậy cho dù nó được mở rộng bao xa thì sẽ luôn cần phải chuyển đổi thứ gì đó. –

+1

Nếu bạn không thích các hạn chế của danh sách tài sản (không thể hỗ trợ NSNull, như tài liệu chỉ ra) thì không sử dụng danh sách thuộc tính. Như người bình luận khác cho thấy, sử dụng định dạng tuần tự của riêng bạn. Hỗ trợ NSPropertyList! = Serialization. – AlBlue

9

Thay vì sử dụng danh sách thuộc tính, hãy xem xét sử dụng NSKeyedArchiver và NSKeyedUnarchiver. Các danh sách thuộc tính có một bộ kiểu cố định và không bao gồm NSNull, và nó không có nghĩa là được mở rộng.

Dưới đây là các liên kết đến tài liệu có liên quan: NSCoding, NSKeyedArchiverNSKeyedUnarchiver.

14

Tôi chuyển đổi NSArray hoặc NSDictionary thành NSData trước khi tuần tự hóa. Sau đây là một danh mục trên nsarray cho serializing và deserializing. comfortableby này xử lý một số dữ liệu là nsnull

@implementation NSArray(Plist) 

-(BOOL)writeToPlistFile:(NSString*)filename{ 
    NSData * data = [NSKeyedArchiver archivedDataWithRootObject:self]; 
    NSArray * paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
    NSString * documentsDirectory = [paths objectAtIndex:0]; 
    NSString * path = [documentsDirectory stringByAppendingPathComponent:filename]; 
    BOOL didWriteSuccessfull = [data writeToFile:path atomically:YES]; 
    return didWriteSuccessfull; 
} 

+(NSArray*)readFromPlistFile:(NSString*)filename{ 
    NSArray * paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
    NSString * documentsDirectory = [paths objectAtIndex:0]; 
    NSString * path = [documentsDirectory stringByAppendingPathComponent:filename]; 
    NSData * data = [NSData dataWithContentsOfFile:path]; 
    return [NSKeyedUnarchiver unarchiveObjectWithData:data]; 
} 
+0

Rất tốt! Các công trình tuyệt vời của nó (mà tôi vừa xác minh) khi các phương thức phổ biến hơn trong các trình lưu trữ có khóa thì không. –

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