2011-02-04 2 views
1

나는 현재 objc_msgSend을 사용하여 객체 컬렉션에서 그러한 selector를 호출한다. 거기에 더 좋은 방법이 있습니까? 여기 내 코드입니다 :스칼라 인자를 가진 Invoke selector

@protocol ADelegateProtocol { 
    -(void) timeToEventOneDidChange:(NSInterval) event1; 
    -(void) timeToEventTwoDidChange:(NSInterval) event1; 
} 

- (void) delegatesPerformSelector:(SEL) selector withTimeIntervalAsFristParameter:(NSTimeinterval) timeInterval { 
    for (id<ADelegateProtocol> delegate in delegates) { 
     if([delegate respondsToSelector:selector]) { 
      objc_msgSend(delegate, selector, timeInterval); 
     } 
    } 
} 

선택기는 매개 변수로 전달되고, timeInterval가 아닌 객체의 값입니다.

참고 : KVO를 사용하고 싶지 않습니다.

+0

은 선택이 매개 변수로 전달되는 추가 질문을 수정하세요.. 그것은 큰 차이를 만듭니다. – taskinoor

+0

전화를 걸고 싶은 방법을 변경하지 않으면 정말 좋아질 것이라고 생각하지 않습니다. 'NSInvocation'은 더 지루합니다. –

+0

뭔가를 놓친다면 용서해주세요. 그러나이 코드는이 메서드에 전달 된 선택기가 인수로'timeInterval'을 사용한다고 가정합니다. 인수가 어떤 것인지 알면 왜 선택자가 될지 알 수 없습니까? 예를 들어, 선택자'forBar :'가 전달 될 수 있는데,'NSTimeInterval'을 인수로 사용합니다. 그러나'fooBaz :'를 문자열로 사용하면'respondsToSelector'는 여전히 true를 반환하지만, 문자열이 예상되어 충돌을 일으키는 시간 간격 ... – Jasarien

답변

8

objc_msgSend()을 사용하려는 경우 은 정확히 유형 변환 포인터를 만들어야이됩니다. 비 varargs에 매핑하기 위해 varargs에 의존하는 것은 모든 경우에 작동하지 않습니다.

e.e. 당신이 원하는 것 :에 입력

void (*myMessage)(id, SEL, NSTimeInterval) = objc_msgSend; 
myMessage(delegate, aSelector, aTimeInterval); 

이 (SO - 구문에게 근사치를 고려 :

+0

흥미 롭습니다. 왜 위의 코드가 더 나은지 말해 줄 수 있습니까? 두 버전을 모두 확인했으며 xcode는 매우 유사한 어셈블리 코드를 생성합니다. –

+0

유일한 차이점은 다음과 같습니다. 당신의 버전 :'mov -0x14 (% ebp), % eax'; 'call * % eax', 원래 호출 :'call 0x13dcfe ' –

+2

ABI의 세부 사항은 시간이 지남에 따라 바뀔 수 있고 (바이너리 호환성 문제를 제외하면), 아키텍처마다 다를 수 있기 때문에. varargs는 비 varargs와 비슷하지만, 정확하지 않고 방어 적이거나 이식 가능하지 않습니다. – bbum

-1

대리인이 NSArray 인 경우 : NSArray의 makeObjectsPerformSelector:(SEL)aSelector을 사용하면 어떨까요?
매개 변수로 개체를 전달해야하는 경우 makeObjectsPerformSelector:(SEL)aSelector withObject:(id)anObject을 사용할 수 있습니다.

+2

질문을 올바르게 이해하면'timeInterval'은 비 객체 값이므로'id'로 쉽게 넘겨 줄 수 없습니다. – zoul

+0

개체에 상자를 넣을 수 있습니다 (예 : NSNumber를 사용하여. – goetz

+2

수신자가 NSNumber를 발송하지 않기 때문에이 작업은 실패합니다. 전체 메서드는 NSNumber를 수락하도록 설계되어야합니다. – JustSid

1

objc_msgSend (당연히 작동) 옆에 사용할 수있는 것은 NSInvocation입니다. 개인적으로 나는 이것을 수행하는 가장 오버 헤드가없는 자유로운 방법으로 objc_msgSend 방법을 선호합니다. 그것도 더 빠른 방법이지만, 이것은 일반 앱 (게임에서는 중요)에서 중요하지 않습니다.

글쎄, 선택은 너의 것인데, objc_msgSend 또는 NSInvocation (ObjC 메서드에서 C 코드가 잘못 보이는 것 외에는)에는 아무런 문제가 없다.