วิธีการเพิ่ม NSNumber


108

ฉันจะเพิ่ม NSNumber ได้อย่างไร

เช่น myNSNumber ++


2
ข้อควรจำ: เมื่อใช้NSNumber *โปรดตรวจสอบเสมอว่าประเภทดั้งเดิมจะเพียงพอหรือไม่
WKS

1
ฉันแปลกใจที่ไม่มีคำตอบที่ให้วิธีการที่รวดเร็ว / เหมาะสมที่สุดเพราะเพียงเพื่อเพิ่มมูลค่าคุณต้องค้นหารวมและสร้างวัตถุใหม่ดังนั้นการทำแบบนี้แบบวนซ้ำอาจใช้เวลานาน
PetrV

คำตอบ:


123

อัปเดต: FYI โดยส่วนตัวแล้วฉันชอบคำตอบแบบบรรทัดเดียวของ BoltClock และ DarkDusts ดีกว่า มีความกระชับมากขึ้นและไม่ต้องการตัวแปรเพิ่มเติม


ในการเพิ่มค่าNSNumberคุณจะต้องได้รับมูลค่าเพิ่มและจัดเก็บเป็นNSNumberไฟล์.

ตัวอย่างเช่นสำหรับการNSNumberถือครองจำนวนเต็ม:

NSNumber *number = [NSNumber numberWithInt:...];
int value = [number intValue];
number = [NSNumber numberWithInt:value + 1];

หรือสำหรับการNSNumberถือครองตัวเลขทศนิยม:

NSNumber *number = [NSNumber numberWithDouble:...];
double value = [number doubleValue];
number = [NSNumber numberWithDouble:value + 1.0];

62
นี่คือเหตุผลอันดับหนึ่งที่ฉันเกลียดคุณสมบัติ NSNumber ใน Core Data NSNumber ไม่สะดวกที่จะทำงานกับคณิตศาสตร์
Christian Schlensker

NSNumber อีกครั้งไม่ทำงานขณะเริ่มต้นด้วยศูนย์ให้ค่าขยะ
Jignesh B

ขอโทษครับย่อมาจาก...อะไร นั่นเป็นการอ้างอิงรหัสหลอกใช่ไหม XCode ไม่...
boulder_ruby

@boulder_ruby ...เป็นเพียงตัวยึดสำหรับหมายเลขใด ๆ ที่คุณต้องการ
Itai Ferber

126

NSNumberวัตถุไม่เปลี่ยนรูป สิ่งที่ดีที่สุดที่คุณสามารถทำได้คือคว้าค่าดั้งเดิมเพิ่มขึ้นจากนั้นรวมผลลัพธ์ไว้ในNSNumberวัตถุของมันเอง:

NSNumber *bNumber = [NSNumber numberWithInt:[aNumber intValue] + 1];

28
ภาษาสมัยใหม่: 1, Objective-C: 0.
devios1

77

สำหรับใครก็ตามที่ใช้ Xcode เวอร์ชันล่าสุด (เขียนเป็น 4.4.1, SDK 5.1) ด้วยการใช้ตัวอักษรของวัตถุคุณสามารถทำความสะอาดโค้ดได้มากขึ้นอีกเล็กน้อย ...

NSNumber *x = @(1);
x = @([x intValue] + 1);
// x = 2

ยังคงเป็นความเจ็บปวดที่ต้องรับมือกับการชกมวยและการแกะทุกอย่างเพื่อดำเนินการง่ายๆ แต่ก็ดีขึ้นเรื่อย ๆ หรืออย่างน้อยก็สั้นลง


6
@softRli ตรวจสอบclang.llvm.org/docs/ObjectiveCLiterals.htmlเพื่อดู ObjC Literalsเพิ่มเติม! imo ที่มีประโยชน์มาก
chown

1
และสำหรับเรื่องนั้นคุณสามารถใช้ x - @ (x.intValue + 1) ได้แม้ว่าหลาย ๆ คนจะไม่ชอบใช้สัญลักษณ์จุดเพื่อเรียกใช้วิธีการที่ไม่ใช่คุณสมบัติ มันสั้นกว่า แต่อาจเรียกได้ว่าเป็นการละเมิดสัญกรณ์จุด
Duncan C

@boulder_ruby เป็นการกำหนดใหม่ NSNumbers ไม่เปลี่ยนรูปดังนั้นในการ "เพิ่ม" ค่าคุณต้องกำหนดค่าใหม่ให้เป็นค่าใหม่
shortstuffsushi

30

NSNumbers ไม่เปลี่ยนรูปคุณต้องสร้างอินสแตนซ์ใหม่

// Work with 64 bit to support very large values
myNSNumber = [NSNumber numberWithLongLong:[myNSNumber longLongValue] + 1];

// EDIT: With modern syntax:
myNSNumber = @([myNSNumber longLongValue] + 1);

24

รวมทั้งหมดเข้าด้วยกันและคุณมี:

myNSNumber = @(myNSNumber.intValue + 1);

คุณไม่ได้กำหนดค่าของ myNSNumber ใหม่ที่นี่หรือ ฉันคิดว่าไม่ได้รับอนุญาตเพราะNSNumberวัตถุไม่เปลี่ยนรูป (?)
boulder_ruby

1
คุณกำลังสร้างวัตถุ NSNumber ใหม่ myNSNumber เป็นตัวชี้ (NSNumber *) และมีค่าใหม่เมื่อคุณทำเสร็จแล้ว
JLundell

3

ฉันชอบนิพจน์ดอทเพราะมันกระชับกว่าและนั่นคือเหตุผลที่IOSรองรับตั้งแต่แรก:

myNSNumber = [NSNumber numberWithInt:myNSNumber.intValue + 1];

สัญกรณ์จุดไม่ได้ทำในสิ่งที่คุณคิดและอาจช้าลงในบางครั้ง (ค่าเริ่มต้นอาจเป็น "valueForKey:" หากไม่มีตัวเข้าถึงสังเคราะห์สำหรับ "คุณสมบัติ" (ในกรณีของคุณเป็น intValue) อยู่ intValue ไม่เคยกำหนดเป็น @property ของ NSNumber
Motti Shneor

2

หากคุณกำลังใช้มันเพื่อเก็บค่าหนึ่ง:

myNSNumber = @(myNSNumber.longLongValue + 1);

สำหรับสิ่งที่เป็นจุดลอยตัวคำตอบสั้น ๆ มีดังต่อไปนี้ แต่เป็นความคิดที่ดีที่จะทำเช่นนี้คุณจะสูญเสียความแม่นยำและหากคุณทำการเปรียบเทียบในภายหลังเช่น [myNSNumber isEqual: @ (4.5)] คุณอาจแปลกใจ :

myNSNumber = @(myNSNumber.floatValue + 1);

หากคุณจำเป็นต้องทำคณิตศาสตร์ในตัวเลขทศนิยมแสดงเป็นวัตถุใน Objective-C (เช่นถ้าคุณต้องการที่จะใส่ไว้ในอาร์เรย์, พจนานุกรม, ฯลฯ ) NSDecimalNumberคุณควรใช้


หากคุณกำลังจะโหวตลงคะแนนก็อาจจะสร้างสรรค์และพูดว่าทำไม
lms

คำตอบของคุณเป็นนัยว่าเป็น NSNumber ที่แนะนำการปัดเศษ woes ไม่ถูกต้อง NSNumber มีพฤติกรรมการปัดเศษเช่นเดียวกับประเภทสเกลาร์ นอกจากนี้คำแนะนำของคุณในการใช้ NSDecimalNumbers ค่อนข้างน่ารำคาญ คุณบอกเป็นนัยว่าสิ่งเหล่านี้จำเป็นหากคุณต้องการสิ่งของพลเมืองคนแรกใน onmbjective-c แต่แน่นอนว่าไม่มีตัวเลขที่วัตถุเช่นกัน NSDecimalNumbers มีความแม่นยำสูงกว่า แต่อาจเกิดข้อผิดพลาดในการปัดเศษขึ้นด้วย และ: op ถามเกี่ยวกับการเพิ่มขึ้นคำตอบของคุณด้วยการลอยตัวและเลขคณิตคู่ แต่สิ่งเหล่านี้ไม่มีการเพิ่มขึ้นเนื่องจากไม่มีผู้สืบทอดตามธรรมชาติ
vikingosegundo

@vikingosegundo เป็นการแปลง NSNumber เป็น float ซึ่งทำให้ความแม่นยำสูญเสียเนื่องจาก NSNumber เก็บตัวเลขไว้เป็นนามธรรมโดยที่ float เป็น base2 ดังนั้นจึงไม่ใช่ความผิดของ NSNumber แต่เป็นการแปลงกลับไปกลับมา และ NSDecimalNumbers จะไม่ทำให้เกิดข้อผิดพลาดในการปัดเศษสำหรับเลขคณิต base10 และได้รับการออกแบบมาสำหรับเลขคณิตโปรดอ่านเอกสาร OP ถามเกี่ยวกับการเพิ่ม NSNumber และฉันก็ให้คำตอบที่ถูกต้องและอ่านได้สำหรับกรณีที่สำคัญและยังให้คำตอบสำหรับกรณีทศนิยม แต่แนะนำให้ต่อต้านแล้วจึงทำตามข้อเสนอแนะที่ดีกว่า
lms

อินสแตนซ์สามารถแทนจำนวนใด ๆ ที่สามารถแสดงเป็นเลขชี้กำลังแมนทิสซา x 10 โดยที่แมนทิสซาเป็นจำนวนเต็มทศนิยมที่มีความยาวไม่เกิน 38 หลักและเลขชี้กำลังเป็นจำนวนเต็มระหว่าง -128 ถึง 127ไม่ใช่ทุกจำนวนที่สามารถแสดงเช่นนี้ได้ OP ยังขอให้เพิ่มได้ง่าย NSDecimalNumber ไม่ได้ระบุไว้ และยังคงคำตอบของคุณเป็นนัยว่าคุณต้องการ NSDecimalNumbers ในพื้นที่วัตถุ ว่าเป็นสิ่งที่ผิด.
vikingosegundo

เพื่อนฉันพยายามช่วยเหลืออย่างแท้จริงกับคำตอบของฉันและคิดว่าการโหวตลดลงเป็นเพราะฉันทำอะไรผิดพลาดและฉันคิดว่าฉันอาจจะได้เรียนรู้สิ่งใหม่ ๆ ตอนนี้ฉันเห็นแล้วว่าไม่ใช่อย่างนั้น ความคิดเห็นของคุณไม่มีเหตุผลและฉันขอแนะนำให้คุณอ่าน uo เกี่ยวกับระบบตัวเลขเพราะเลขฐาน 10 sys (เรื่องคำพูดของคุณ) จะไม่ทำให้เกิดข้อผิดพลาดในการปัดเศษสำหรับเลขฐาน 10 ฉันไม่ได้พูดอะไรเกี่ยวกับความแม่นยำความแม่นยำ แต่ 128 ทศนิยมก็มีความแม่นยำมากมายเช่นกัน
lms

0

ใช้หมวดหมู่เพื่อสะดวกในการใช้งานในอนาคต นี่คือแนวคิดพื้นฐาน

 - (void)incrementIntBy:(int)ammount {
      self = [NSNumber numberWithInt:(self.intValue + ammount)];
 }

ฮึ. หมวดหมู่ที่ใช้วิธีการอินสแตนซ์ที่แทนที่ตัวเอง!? ที่น่ารังเกียจอย่างยิ่ง ทำไมไม่เขียนวิธีการอินสแตนซ์ที่มีผลตอบแทนที่ไม่ใช่โมฆะของ NSNumber ที่เป็นผลลัพธ์
ดันแคนค

NSNumber ถูกกำหนดให้ไม่เปลี่ยนรูปด้วยเหตุนี้วิธีการหมวดหมู่นี้จึงละเมิดความสามารถในการเปลี่ยนรูปที่ควรจะเป็น (แม้ว่าจะแทนที่ตัวเอง) หมวดหมู่ดังกล่าวที่ออกแบบมาดีกว่าจะเพิ่มตัวเริ่มต้นใหม่ให้กับ NSNumber ในรูปแบบ: + numberByIncrementingAmounf: (int) amount;
Motti Shneor

0

ข้อมูลดีๆมากมายในคำตอบสำหรับคำถามนี้ ฉันใช้คำตอบที่เลือกในรหัสของฉันและได้ผล จากนั้นฉันก็เริ่มอ่านบทความที่เหลือและทำให้โค้ดง่ายขึ้นมาก อ่านยากกว่าเล็กน้อยหากคุณไม่คุ้นเคยกับการเปลี่ยนแปลงสัญกรณ์ที่เปิดตัวใน Xcode 5 แต่จะสะอาดกว่ามาก ฉันอาจจะทำให้มันเป็นแค่บรรทัดเดียว แต่มันก็ยากเกินไปที่จะคิดออกว่าฉันกำลังทำอะไรอยู่

ฉันกำลังจัดเก็บ NSNumber ในพจนานุกรมและต้องการเพิ่มจำนวน ฉันเข้าใจแล้วแปลงเป็น int เพิ่มขึ้นในขณะที่แปลงเป็น NSNumber จากนั้นใส่กลับเข้าไปในพจนานุกรม

รหัสเก่า

 NSNumber *correct = [scoringDictionary objectForKey:@"correct"];
 int correctValue = [correct intValue];
 correct = [NSNumber numberWithInt:correctValue + 1];
 [scoringDictionary removeObjectForKey:@"correct"];
 scoringDictionary[@"correct"] = correct;

รหัสใหม่

NSNumber *correct = [scoringDictionary objectForKey:@"correct"];
scoringDictionary[@"correct"] = @(correct.intValue + 1);
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.