2014-09-06 4 views
9

ओके टीम में अजीब तरीके से व्यवहार कर रहा है, यह अजीब है। [NSDecimalNumber integerValue] अजीब व्यवहार कर रहा है।{NSDecimalNumber integerValue} आईओएस 8

मैं एक ब्रेकपॉइंट पर बैठा हूं, यह पता लगाने की कोशिश कर रहा हूं कि मेरे ऐप के कुछ हिस्सों को आईओएस 8 में क्यों टूटा गया है, और मैं "टाइमसेकंड" नामक एक चर को देख रहा हूं। यह Xcode चर में इस तरह दिखाई देता है देखें:

_timeSeconds (NSDecimalNumber *) 344.514533996581994496 

लेकिन जब मैं डीबगर में क्वेरी, मैं इस देखें:

(lldb) p [self.timeSeconds doubleValue] 
(double) $14 = 344.51453399658192 
(lldb) p [self.timeSeconds intValue] 
(int) $15 = 344 
(lldb) p [self.timeSeconds integerValue] 
(NSInteger) $16 = -5 
(lldb) p (NSInteger)[self.timeSeconds intValue] 
(NSInteger) $17 = 344 

कि "-5" देखते हैं? क्या आप में से कोई भी सुंदर लोग पुनरुत्पादन या व्याख्या कर सकता है, इससे पहले कि मैं रडार दर्ज करूं?

NSDecimalNumber *n = [NSDecimalNumber decimalNumberWithString:@"344.514533996581994496"]; 
NSLog(@"%@", n); // 344.514533996581994496 
NSLog(@"%ld", (long)[n intValue]); // 344 
NSLog(@"%ld", (long)[n integerValue]); // -5 
NSLog(@"%ld", (long)[n unsignedIntegerValue]); // 12 

अग्रिम धन्यवाद:

यहाँ SSCCE है!

मैथ्यू

+0

मैथ्यू - आपको क्या मिला? आईओएस 8 पर NSDecimalNumber मेरे लाइव ऐप में बड़ी समस्याएं पैदा कर रहा है! – SAHM

उत्तर

12

के लिए integerValue परिणाम आश्चर्य की बात है, लेकिन मैं क्या समझ दस्तावेज के रूप में से: NSNumber से

NSDecimalNumber इनहेरिट करती है। से सबक्लासिंग नोट्स में NSNumber यह कहा गया है कि "... उपclass को घोषित प्रकार से मेल खाने वाले एक्सेसर विधि को ओवरराइड करना होगा - उदाहरण के लिए, यदि आपके ऑब्जेक्टिप के कार्यान्वयन को" i "देता है, तो आपको intValue ओवरराइड करना होगा .. । "

objCType भीतरी सूचक के लिए सेट है, तो यह NSNumber के लिए के रूप में ही होना चाहिए।

NSDecimalintergerValue हावी नहीं होता। यह डबलवैल्यू ओवरराइड करता है, ताकि ठीक काम करना चाहिए।

केवल एक चीज मुझे आश्चर्य है कि बनाता है: यह intValue या तो ...

+0

मुझे लगता है कि आप निश्चित रूप से सही रास्ते पर हैं। मैं इसे थोड़ा बेहतर समझना चाहता हूं और यदि आप intValue के बारे में पता लगाते हैं, तो कृपया अपना उत्तर पोस्ट करें। लेकिन मैं आगे बढ़ने जा रहा हूं और बक्षीस का पुरस्कार दूंगा क्योंकि मुझे लगता है कि यह सही दिशा है और मैं नहीं चाहता कि बक्षीस आपको इसे देने के बिना बाहर निकल जाए। – SAHM

+0

यह एक संबंधित प्रश्न है जहां एनएसडीसीमल समस्या का एक और विशिष्ट मामला है जो इस मुद्दे से संबंधित है। http://stackoverflow.com/questions/26741233/ios-8-number-conversion-formatting-error-cannot-reproduce – SAHM

2

क्या एक महान बग पर हावी नहीं होता लगता है! मैंने बस खुद को धोखा दिया। तो, बस समाप्त करने के लिए dogsgods का जवाब:

नहीं है:

NSInteger x = [myDecimalNumber integerValue]; 

इसके बजाय, ऐसा करते हैं:

NSInteger x = (NSInteger)[myDecimalNumber doubleValue]; 
0

आप उपयोग intValue या unsignedIntValue उपयोग कर सकते हैं बस ठीक है, लेकिन नहीं पूर्णांक वैल्यू या unsignedIntegerValue।यहां एक यूनिट टेस्ट है जो इस मुद्दे को प्रदर्शित करता है, यह दर्शाता है कि यह 64 से अधिक बिट्स की आवश्यकता वाले नंबरों से संबंधित है:

// 
// NSDecimalNumberBugTests.m 
// 
// Created by Lane Roathe on 6/1/17. 
// For Quicken, Inc. 
// 

#import <XCTest/XCTest.h> 

@interface NSDecimalNumberBugTests : XCTestCase 

@end 

@implementation NSDecimalNumberBugTests 

- (void)setUp { 
    [super setUp]; 
    // Put setup code here. This method is called before the invocation of each test method in the class. 
} 

- (void)tearDown { 
    // Put teardown code here. This method is called after the invocation of each test method in the class. 
    [super tearDown]; 
} 

- (void)testBug { 
    // Use XCTAssert and related functions to verify your tests produce the correct results. 
    NSDecimalNumber* decimalLength; 
    NSUInteger interval; 

    // Start with a number that requires 65+ bits 

    // This FAILS (interval is zero) 
    decimalLength = [NSDecimalNumber decimalNumberWithString:@"1.8446744073709551616"]; 
    interval = decimalLength.unsignedIntegerValue; 
    XCTAssert(interval == 1); 

    // This Works, interval is 1 
    interval = decimalLength.unsignedIntValue; 
    XCTAssert(interval == 1); 

    // Now test with a number that fits in 64 bits 

    // This WORKS (interval is 1) 
    decimalLength = [NSDecimalNumber decimalNumberWithString:@"1.8446744073709551615"]; 
    interval = decimalLength.unsignedIntegerValue; 
    XCTAssert(interval == 1); 
} 

@end