Objective-C 산 할당을 반환 할당된 값?
-
20-09-2019 - |
문제
나는 다음과 같다:
@interface MyClass : NSObject { NSString* _foobar; }
@property (nonatomic, retain) NSString* foobar;
@end
@implementation MyClass
@dynamic foobar;
- (void) setFoobar:(NSString*)fbSet; { [_foobar release]; _foobar = [fbSet retain]; }
- (NSString*) foobar; { return _foobar; }
@end
다음:
MyClass* mcInst = [[[MyClass alloc] init] autorelease];
NSLog(@"I set 'foobar' to '%@'", (mcInst.foobar = @"BAZ!"));
보고는 반환 값의 -[MyClass setFoobar:]
, 한한다고 가정 할 수 있습 여기에는 이 라인 것 인쇄 I set 'foobar' to ''
, 기 때문에 할당을 나타나게 아무것도 반환하지 않습니다.
그러나 다행히-본 과제 행위로 예상되,그리고 코드 인쇄 I set 'foobar' to 'BAZ!'
.불행하게도,이 모순 같은 느낌이 들기 때문에,호출되는 세터의 반환 값을 속이는 사실에 할당 값을 반환 할당되어 있습니다.처음에 나는 mcInst.foobar = @"BAZ!";
은 두 개의 전화를 대신 블:첫 번째 세터와 다음의 게터를 수집하는 반환 값.그러나,계측 세터 및 getter 방법 NSLog
전화 증명이 실제로는 그렇지 않습니다.
해결책
빠른 요약:
빠른 여기에 해답이 없다는 것입니다 모순이기 때문에,식의 결과는:
(mcInst.foobar = @"BAZ!")
실제로 @"BAZ!"
, 고 지 mcInst.foobar
.
더 자세한 내용은 아래 사용할 수 있지만,그것은 도움이 될 수 있습을 고려하는 다음과 같은 수정 setFoobar
방법:
- (void) setFoobar:(NSString*)fbSet
{
[_foobar release];
_foobar = [[NSString stringWithFormat:@"HELLO_%@", fbSet] retain];
}
이 코드는 장소에서 값 foobar
숙박 시설은 수정되는 동안정, 하지만 라인의 코드가 여전히 표시하는 값'BAZ!'.
상세정보:
으로 지적하여 newacct, 의 NSLog 코드를 작동하기 때문에 당신이 사용하여 할당자(=)있는,매우 특정한 행위에는 C 언어(어떤 목표-C 에 기초)
C 에서는 다음을 수행할 수 있습니다:
x = y = z = 42;
의 모든 변수, x
, y
고 z
값을 보유하 42.
컴파일러 손잡이 이 행동을 사용하여 일시적 변수(*).기본적으로,무대 뒤에서 일어나는 다음과 같이 나타납니다.
tempVar = 42;
z = tempVar;
y = tempVar;
x = tempVar;
같은 라인을 따라,다음을 수행할 수 있습니다:
SomeFunction(x = 42);
이 라인의 코드의 값을 복사 42 로 x,그리고 그런 다음 전화 SomeFunction
과 함께 인수의 42.뒤에서,그것은 다음과 같습니다:
tempVar = 42;
x = tempVar;
SomeFunction(tempVar);
지금,Objective-C,로깅 라인은 다음과 같이 처리됩니다:
tempVar = @"BAZ!";
[mcInst setFooBar:tempVar];
NSLog(@"I set 'foobar' to '%@'", tempVar);
(*)이의 사용법"temporaray 변수는"나는 설명하는 것은 의미를 설명하는 개념,그리고 실제로 반영 주어진 실제로는 컴파일러가 있습니다.그런 종류의 구현 세부사항을 프로그래머를 쓰는 컴파일러,각각의 하나는 할 수 있습니다.최종 결과는,그러나,동일합니다.
다른 팁
게터를 호출 할 필요가 없습니다. 같은 줄에 바로 할당되는 값이 있습니다. 당신은 그것을 확장한다고 생각할 수 있습니다 [mcInst setFoobar:@"BAZ!"], @"BAZ!"
.
C에서 할당은 할당 된 값으로 평가하는 표현식입니다.
이는 C 할당 연산자의 작동 방식 때문입니다. ANSI C 표준에 설명 된대로 :
"과제 연산자는 왼쪽 피연산자가 지정된 객체에 값을 저장합니다. 과제 표현식은 할당 후 왼쪽 피연산자의 값을 갖습니다 ..."
당신의 과제 표현 mcInst.foobar = @"BAZ!"
. McInst의 메소드를 C와 동일하게 행동하는 방법을 호출함으로써 할당이 작동하지만 할당 표현식의 값은 할당 후 왼쪽 피연산자입니다 (@"BAZ!"
) 따라서이 값은 NSLOG 함수로 전달됩니다.
이것은 스타일로 이니셜 라이저를 쓸 수있는 동일한 동작입니다. if (self = [super init])
.
추신 : 값을 할당 할 때 컴파일러가 속성에 세터를 호출하고 값을 사용할 때 getter를 호출하지 않는 이유를 묻는 것이 공정한 질문입니다. mcInst.foobar
나중에. 나는 그것이 단순히 Getter가 부동산에 배정 된 것과 동일한 값을 반환 할 것이라고 가정하므로 Getter는 호출되지 않습니다.