2010-07-23 3 views
2

here의 (멋진) 안내를 따르려고하지만 하위 클래스로 수정할 수없는 클래스 인스턴스가 있습니다. 메서드를 클래스의 인스턴스에만 재정의 할 수있는 방법이 있습니까?Monkey 패치 Objective-C로

답변

6

주의하십시오. 여러분은 ObjC에서 꽤 심오한 마법을 시작하려고합니다. 그리고 여러분이 생성 할 수있는 버그의 종류는 마음을 굽히는 것입니다. 이것들은 다른 모든 것이 실패한 후에 사용해야 할 마지막 기술이며,이 코드를 분리하기 위해 할 수있는 일은 무엇이든해야합니다. 즉, ObjC는 매우 동적 인 언어이므로 대부분의 것을 다시 연결할 수 있습니다.

먼저 특정 질문에 대해 인스턴스의 클래스를 변경하면 원하는 것을 얻을 수 있습니다. 규칙은 기본적으로 다음과 같습니다

  • 새로운 클래스는 새로운 클래스는 모든 인스턴스 변수를 추가하지 않아야 전자의 클래스를
  • 의 서브 클래스이어야한다. 하위 클래스에 ivars를 추가하는 것은 위에서 언급 한 mind-bending 버그로 이어질 수있는 것들 중 하나입니다.

잘못 입력하면 경고 나 오류가 표시되지 않습니다. 기괴한 사고를 당하게 될 것입니다.

는 객체의 클래스를 변경하면 실제로 매우 간단하다는 것을 감안할 때 : 그 너머

object->isa = [NewClass class]; 

, 당신은 방법 스위 즐링을 사용하여 클래스의 모든 인스턴스에 대해 메소드의 구현을 변경할 수 있습니다. 나는 이것의 몇 가지 예를 Hijacking with method_exchangeImplementations()에 가지고있다. 그래도 일단 디버거를 사용하면 행운을 빈다.

+0

고마워요. 매혹적이지만, 저의 강점을 고수하고이를 회피 할 것을 확신했습니다. –

+0

실제로, 너무 나쁘지는 않지만 사실 내 경우에는 잘될 수도 있습니다. –

+1

신중하게 사용하면 실제로는 매우 간단합니다. 프로그램의 나머지 부분에 관심이 없는지 확인하기 위해 할 수있는 모든 일을하십시오. 이것은 KVO가 구현되는 방법의 일부입니다. KVO로 처음으로 객체를 관찰하면 클래스가 모든 접근자를 수정하는 마법 KVO 하위 클래스로 전환됩니다. 그것은 모두 잘 작동하고, 당신도 알지 못합니다. 하지만 KVO 코드 자체 디버깅은 기껏해야 즐겁습니다. 당신의 문제와 동일합니다. 그냥 잘 문서화하거나 당신이 무엇을하고 있었는지 결코 기억하지 못할 것입니다. –

1

실제로 서브 클래 싱을 사용하여 수정할 수 있습니다. 그것은 당신이 할 수있는 더 섬세한 것들 중 하나이며, 대신 메서드 swissling 볼 수 있습니다 (그러나 메서드 swizling 클래스의 모든 구성원에게 영향을 미칠 것입니다),하지만 객관적인 c, 모든 개체의 클래스를 설정하려면 매우 쉽습니다. 기본적으로해야 할 일은 여분의 ivars를 선언하지 않는 서브 클래스를 선언하고 필요한 메소드를 오버라이드 한 다음 (그리고 아마도 슈퍼 구현을 호출하기를 원할 것입니다), 런타임에 객체의 클래스를 변경하는 것입니다 object_setClass (에서 선언).

+0

감사합니다. –