2009-07-22 2 views
1

최근 코드에서 예상치 못한 컴파일 오류로 인해 매우 혼란 스러웠습니다. 나는 몇 가지 문제 해결을했고, 나는 테스트 코드의이 비트를 내놓았다 :performSelector에 대한 검색 결과 : 표준 점 표기법 호출과 다른가요?

1 float performSelectorResult, messageResult; 
2 SEL selector = @selector(smallContentCellMargin); 
3 
4 NSLog (@"selector %s result %f", selector, [defaults performSelector:selector]); 
5 NSLog (@"message result is %f", defaults.smallContentCellMargin); 
6 
7 performSelectorResult = [defaults performSelector:selector]; 
8 messageResult = defaults.smallContentCellMargin; 

을, 나는 7 호선에 컴파일 오류가 발생 될 때-I이 코드를 실행하면 "호환되지 않는 유형의 할당에". 그러나 7 행을 주석 처리하면 코드가 빌드되고 실행됩니다. NSLog의 결과는 다음과 같습니다.

2009-07-21 18:31:44.823 ICE[24347:20b] selector smallContentCellMargin result 0.000000 
2009-07-21 18:31:44.830 ICE[24347:20b] message result is 7.000000 

매우 유사한 코드를 사용하여 UIFont를 검색했지만 float는 사용하지 않았습니다. 내가 모르는 뭔가가 있습니까, 아니면 Objective-C의 버그입니까? 나는 매우 혼란 스럽다.

답변

3

먼저 NSLog로 로깅 할 때 선택기를 문자열로 처리합니다. 그러지 마세요 - SEL은 문자열이 아닙니다. % @ 형식과 NSStringFromSelector (aSelector)를 사용하십시오.

문제의 경우, -performSelector :는 개체 반환 형식이있는 선택기와 함께 작동하도록 정의됩니다. ABI로 인해 포인터의 크기까지 int 반환 유형에 대해 (런타임 구현 세부 사항에 따라)이 문제를 해결할 수 있지만, 일반적으로 플로트 반환 값에 대해 알아 차릴 수는 없습니다.

개체가 아닌 값의 경우 NSInvocation 또는 -valueForKey :를 사용해야합니다. 후자의 경우에는 NSNumber로 부동 상자가 생성됩니다.

+0

-valueForKey의 빠른 테스트를 시도했습니다. 'float quickTest = [defaults valueForKey : @ "smallContentCellMargin"];' 코드를 컴파일하려고하면 "초기화 할 수없는 유형"오류가 발생합니다. 문서에서 --valueForKey를 찾았는데 형식 (ID)을 반환한다고합니다. 잘못된 것이 있습니까? 아니면이 경우에는 -performSelector와 동일합니까? – JoBu1324

+2

+1 메시지를 실제로 전달하는 방법에 대해 자세히 알 수있는 좋은 기회입니다. 우리는 종종 메시지가 w/objc_msgSend()로 전달된다고 말하지만 단순화 된 것입니다. docs에서 objc_msgSend()를 찾아 친구들과 비교하십시오.이 경우 objc_msgSend_fpret()를 사용하십시오. OP 코드 *는 PPC에서 작동하지만 인텔에서는 작동하지 않습니다. 그리고 그것은 당신이 의존하고 싶지 않은 종류의 플랫폼 의존성입니다. Jim의 접근법을 사용하십시오. Intel에서이 정보를 얻을 수있는 곳이라 할지라도. –

+0

-valueForKey에 대한 Jim의 의견을 다시 읽습니다. NSNumber를 반환합니다. NSNumber는 숫자 (이 경우에는 double)를 나타내는 객체입니다. –