NSNumber를 증가시키는 방법


108

NSNumber는 어떻게 증가합니까?

즉 myNSNumber ++


2
기억하십시오 :를 사용할 때 NSNumber *항상 기본 유형이 충분한 지 확인하십시오.
WKS

1
빠른 / 최적화 된 방법을 제공하는 답이 없다는 것에 놀랐습니다. 값을 높이려면 쿼리, 결합 및 새 개체를 만들어야하므로 루프에서이 작업을 수행하는 데 시간이 많이 걸릴 수 있기 때문입니다.
PetrV 2014.06.14

답변:


123

업데이트 : 참고로, 저는 개인적으로 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
이것이 제가 Core Data에서 NSNumber 속성을 싫어하는 가장 큰 이유입니다. NSNumber는 작업하고 수학을 수행하는 데 너무 불편합니다.
Christian Schlensker 2011 년

다시 NSNumber는 0으로 초기화하는 동안 작동하지 않고 가비지 값을 제공합니다.
Jignesh B

죄송합니다. 무슨 뜻 ...입니까? 그게 의사 코드 참조입니까? XCode는하지 않습니다...
boulder_ruby 2014-02-23

@boulder_ruby ...는 원하는 숫자에 대한 자리 표시 자입니다.
Itai Ferber 2014

126

NSNumber객체는 불변입니다. 당신이 할 수있는 최선의 방법은 프리미티브 값을 잡고 그것을 증가시킨 다음 그 결과를 자체 NSNumber객체 로 감싸는 것입니다 :

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

28
현대 언어 : 1, Objective-C : 0.
devios1 2013-08-11

77

객체 리터럴을 사용하여 최신 버전의 Xcode (4.4.1, SDK 5.1로 작성)를 사용하는 사람이라면 코드를 조금 더 정리할 수 있습니다.

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

복싱을 처리하고 모든 것을 개봉하여 간단한 작업을 수행하는 것은 여전히 ​​고통 스럽지만 점점 좋아지고 있거나 적어도 짧아지고 있습니다.


6
@softRli 더 많은 ObjC 리터럴을 보려면 clang.llvm.org/docs/ObjectiveCLiterals.html 을 확인하십시오! 매우 편리한 이모.
chown

1
그리고 그 문제에 대해 x-@ (x.intValue + 1)을 사용할 수 있지만 많은 사람들이 비 속성 메서드를 호출하기 위해 점 표기법을 사용하는 것을 좋아하지 않습니다. 더 짧지 만 점 표기법의 남용이라고 할 수 있습니다.
Duncan C

@boulder_ruby, 재 할당입니다. NSNumber는 변경할 수 없으므로 값을 "증가"하려면 실제로 새 값에 다시 할당해야합니다.
shortstuffsushi

30

NSNumber는 변경할 수 없으므로 새 인스턴스를 만들어야합니다.

// 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 2014

3

점 표현이 더 간결하기 때문에 IOS 가 처음부터 지원하는 이유입니다 .

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

점 표기법은 사용자가 생각하는대로 작동하지 않으며 때때로 느려질 수 있습니다 ( "property"(귀하의 경우 intValue)에 대해 합성 된 접근자가 존재하지 않는 경우 기본값은 "valueForKey :"로 설정 될 수 있음). intValue는 @property로 정의되지 않았습니다. of NSNumber.
Motti Shneor

2

정수 값을 저장하는 데 사용하는 경우 :

myNSNumber = @(myNSNumber.longLongValue + 1);

부동 소수점의 경우 짧은 대답은 다음과 같지만 이렇게하는 것은 나쁜 생각입니다. 정밀도가 떨어지고 나중에 [myNSNumber isEqual : @ (4.5)]와 같이 어떤 종류의 비교를 수행하면 놀랄 수 있습니다. :

myNSNumber = @(myNSNumber.floatValue + 1);

Objective-C에서 객체로 표현 된 부동 소수점 숫자에 대해 수학을 수행해야하는 경우 (즉, 배열, 사전 등에 배치해야하는 경우)를 사용해야합니다 NSDecimalNumber.


반대표를 던지는 경우 건설적이고 그 이유를 말할 수 있습니다.
lms

귀하의 대답은 반올림 문제를 도입하는 것이 NSNumber임을 의미합니다. 올바르지 않습니다. NSNumber는 스칼라 유형과 동일한 반올림 동작을 갖습니다. 또한 NSDecimalNumbers 사용에 대한 귀하의 조언은 매우 짜증납니다. onmbjective-c에서 첫 번째 시민 객체가 필요한 경우 해당 항목이 필요하다는 것을 암시합니다. 그러나 물론 nsnumbers는 객체에서도 마찬가지입니다. NSDecimalNumbers는 정밀도가 더 높지만 반올림 오류도 발생할 수 있습니다. 그리고 : op는 증가에 대해 묻고 부동 및 이중 산술로 대답합니다. 그러나 자연적인 후계자가 없기 때문에 증가가 없습니다.
vikingosegundo

@vikingosegundo NSNumber는 float가 base2 인 곳에 숫자를 추상적으로 저장하기 때문에 정확도 손실을 일으키는 float로 변환하는 것이므로 NSNumber의 잘못이 아니라 앞뒤로의 변환입니다. 그리고 NSDecimalNumbers는 것입니다 하지 원인 연산 유효한 시간에 대한 오류를 반올림, 그들은이 되어 해당 문서를 읽고, 연산을 위해 설계. OP는 NSNumber를 증가시키는 것에 대해 물었고, 나는 그에게 적분 케이스에 대해 정확하고 읽기 쉬운 대답을했고 또한 부동 소수점 케이스에 대한 대답을 주었지만 그것에 대해 조언하고 더 나은 제안을 따랐습니다.
lms

인스턴스는 가수 x 10 지수로 표현할 수있는 모든 숫자를 나타낼 수 있습니다. 여기서 가수는 최대 38 자리의 십진 정수이고 지수는 -128에서 127 사이의 정수입니다. 모든 숫자가 이와 같이 표현 될 수있는 것은 아닙니다. 또한 OP는 쉬운 증분을 요구했습니다. NSDecimalNumber는 그것을 제공하지 않습니다. 여전히 귀하의 대답은 객체 공간에 NSDecimalNumbers가 필요하다는 것을 의미합니다. 그건 틀렸어요.
vikingosegundo

야 나는 내 대답에 진정으로 도움이 되려고 노력하고 있었고, 내가 뭔가 잘못되었고 새로운 것을 배울 수 있다고 생각했기 때문에 반대표가 있다고 생각했습니다. 이제는 그렇지 않다는 것을 알 수 있습니다. 귀하의 의견은 의미가 없으며 기본 10 숫자 시스템이기 때문에 숫자 시스템에 대한 읽기를 제안합니다. (Re. your quote) 기본 10 숫자에 대해 반올림 오류가 발생하지 않습니다. 정밀도에 대해서는 아무 말도하지 않았고, 정확도에 대해서는 언급하지 않았지만, 십진수 128도 정밀도가 충분합니다.
lms

0

나중에 쉽게 사용할 수 있도록 카테고리를 사용하십시오. 여기에 기본적인 아이디어가 있습니다.

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

으. self?!?를 대체하는 인스턴스 메서드를 구현하는 범주 그것은 심각하게 불쾌합니다. 결과 NSNumber를 무효로 반환하지 않는 인스턴스 메서드를 작성하지 않는 이유는 무엇입니까?
던컨 C

NSNumber는 불변으로 정의되어 있으므로이 범주 메서드는 (self를 대체하더라도) 예상되는 불변성을 위반합니다. 더 잘 설계된 이러한 범주는 대신 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.