2010-11-20 37 views
5

Đầu tiên tôi thú nhận sự thiếu hiểu biết của mình, tôi đã học được mọi thứ tôi biết về Objective-C trong vài tháng tôi đã làm việc trong dự án của mình. Tôi cũng tìm thấy nó hoàn toàn bực bội như thế nào Objective-C dường như phức tạp những gì sẽ là những vấn đề đơn giản trong bất kỳ ngôn ngữ khác mà tôi đã làm việc với. Câu hỏi này là một trường hợp ...Cách kiểm tra giá trị null trong NSNumber

Trong lần chạy đầu tiên, ứng dụng của tôi tải xuống một loạt JSON mà nó sử dụng để điền một kho lưu trữ CoreData. Tôi sử dụng một thư viện Obj-C/JSON (CJSONDeserializer) để chuyển đổi JSON thành NSArrays. Trong bản tải xuống JSON cho một thực thể CoreData có một trường có chứa một số ("show_id":2) xác định trường có liên quan trong một thực thể khác nếu có một hoặc null ("show_id":null) nếu không. Trong việc xử lý lĩnh vực mà tôi gán nó vào một NSNumber sử dụng ...

NSNumber *shoIndex = [[item objectForKey:typeKey] objectForKey:@"show_id"]; 

sau đó tôi cố gắng để kiểm tra xem tôi có một số hợp lệ trước khi cố gắng lấy & liên kết biểu ghi liên quan để không làm lãng phí chế biến, nơi có không có hồ sơ liên quan.

Chất vấn shoIndex với ...

NSLog(@"shoIndex: %i, %@, %@", shoIndex, shoIndex, [shoIndex description]); 

Cung cấp cho ...

shoIndex: 19590600, <null>, <null> 

trong đó giá trị JSON là null & ...

shoIndex: 228300880, 51, 51 

khác.

Cho đến nay việc kiểm tra thành công duy nhất mà tôi đã thực hiện là với ...

if (![[shoIndex description] isEqualToString:@"<null>"]) { 

bất cứ ai có thể đề xuất một cách tốt hơn?

Update ...

Nhìn vào nó một cách khác shoIndex được gán như một NSNumber rằng đôi khi chứa một giá trị NSString@"<null>". Liệu Obj-C có cái gì đó giống như một toán tử isa mà tôi có thể sử dụng để kiểm tra loại nội dung của shoIndex?

TIA, Pedro.

+0

Điều gì làm cho bạn nghĩ rằng đối tượng là một thể hiện của 'NSNumber'? – jlehr

Trả lời

10

Sử dụng [shoObject class] để lấy lớp của đối tượng; như vậy, để kiểm tra shoObject 's lớp, bạn sẽ sử dụng

[shoObject isKindOfClass:[NSString class]]; 

Khi bạn đã sắp xếp ra những gì các dấu hiệu xác định một chuỗi rỗng hoặc NSNumber, bạn có thể tạo một macro. Tôi làm điều này bằng cách giữ một macro IsEmpty trong một tập tin gọi là CommonMacros.h. Đây là mã:

//Thanks Wil 
//http://wilshipley.com/blog/2005/10/pimp-my-code-interlude-free-code.html 

static inline BOOL IsEmpty(id thing) { 
    return thing == nil 
    || ([thing isEqual:[NSNull null]]) //JS addition for coredata 
    || ([thing respondsToSelector:@selector(length)] 
     && [(NSData *)thing length] == 0) 
    || ([thing respondsToSelector:@selector(count)] 
     && [(NSArray *)thing count] == 0); 
} 

Sau đó, sau khi nhập CommonMacros.h, bạn có thể gọi hàm như sau:

if (IsEmpty(shotIndex)) { 
    //do stuff 
} 

Điều này sẽ giải quyết vấn đề này và cũng sẽ hoạt động trên chuỗi, mảng, v.v ... như bạn có thể thấy từ mã. Cảm ơn Wil Shipley!

+0

Cảm ơn Wil, điều đó có tác dụng. Nhìn vào URL bạn đã cung cấp ở đó tôi nghĩ bạn đã giúp tôi theo những cách khác :) – Pedro

+0

Tôi đã nói quá sớm. Tôi muốn làm công cụ nếu shoIndex không rỗng vì vậy tôi đã cố gắng! IsEmpty (shoIndex) và NSNumber của tôi bay thẳng mặc dù nó. – Pedro

+0

Hmm, kỳ quặc, điều đó quá tệ. Tôi sẽ đề nghị thêm isEqualToString này: @ "" kiểm tra mã IsEmpty, nhưng tất nhiên né tránh tuyến đường đó là lý do bạn hỏi câu hỏi này ngay từ đầu. –

-1

Trong mục tiêu-c, nó là nil không null. Vì vậy:

if (shotIndex != nil) { 
    // its not nil 
} 
+2

Đây chính xác là những gì tôi đã thử lần đầu tiên và nó không hoạt động. Nơi bạn nhìn thấy trong câu hỏi của tôi đó là những gì NSLog cung cấp cho NSNumber nơi mục JSON là null. – Pedro

+0

Đây là JSON. Nếu shotIndex không có trong dữ liệu JSON, thì nó sẽ là không. Tuy nhiên, như Pedro đã nói, các shotIndex đã có mặt với một giá trị null, và các trình phân tích cú pháp JSON sẽ cung cấp cho bạn một giá trị của [NSNull null], không phải là không. Việc gửi hầu hết các tin nhắn tới [NSNull null] sẽ bị lỗi, vì vậy đây là một sự khác biệt quan trọng. – gnasher729

0

Trong một số trường hợp, chẳng hạn như các phím bị thiếu trong NSUserDefaults, bạn lấy lại ký tự @ "" dưới dạng chuỗi rỗng.

Đây là kiểm tra an toàn cho một NSNumber của tôi.

Lưu ý việc kiểm tra cho nó trở thành một NSNumber xảy ra trước vì NSNumber không hiểu isEqualToString

 id savedPin = [[NSUserDefaults standardUserDefaults] valueForKey:@"blah"]; // don't assume is created so don't type as NSNumber* 
     if (![savedPin isKindOfClass:[NSNumber class]] && [savedPin isEqualToString:@""]) { 
Các vấn đề liên quan