문제

소스가없는 목표 C 클래스의 메소드를 무시하고 싶습니다.

나는 그것을 살펴 보았고, 카테고리를 사용하면이 작업을 수행 할 수 있어야하지만, 새 메소드에서 기존 메소드의 결과를 사용하여 Super를 사용하여 이전 메소드 결과를 얻을 수 있습니다.

그래도 시도 할 때마다 내 방법이 호출되지만 "Super"는 Nil입니다 ... 그 이유는 무엇입니까? Xcode 2.2 SDK로 iPhone 개발을하고 있습니다. 나는 수업 인스턴스로 확실히 작업하고 있으며, 수업의 방법은 인스턴스 방법입니다.

@implementation SampleClass (filePathResolver)
-(NSString*) fullPathFromRelativePath:(NSString*) relPath
{
    NSString *result = [super fullPathFromRelativePath: relPath];

  ... do some stuff with the old result

    return result;
}

참고 및 설명 : Apple 문서에서 볼 수있는 내용에서 이것이 허용되어야하는 것처럼 보입니까?

Developer.apple.com의 카테고리 문서 :카테고리가 상속 메소드를 무시하면 범주의 메소드는 평소와 같이 메시지를 통해 상속 된 구현을 수퍼에게 호출 할 수 있습니다. 그러나 카테고리가 카테고리 클래스에 이미 존재했던 메소드를 무시하면 원래 구현을 호출 할 방법이 없습니다.

도움이 되었습니까?

해결책

카테고리는 원래 클래스를 확장하지만 서브 클래스는 아니므로 super 방법을 찾지 못합니다.

당신이 원하는 것을 불립니다 방법 스위 즈 링. 그러나 코드가 무언가를 깨뜨릴 수 있다는 점에 유의하십시오. 에 관한 기사가 있습니다 Scot Stevenson이 작성한 Theocacao 오래된 Objective-C 런타임에서 스위글링하는 방법에 대해 Matt Gallagher의 사랑과 코코아 새로운 Objective-C 2.0 런타임에서 Swizzling 방법과 간단한 교체에 관한 기사가 있습니다.

또는 클래스를 서브 클래스 한 다음 서브 클래스를 사용하거나 사용 할 수 있습니다. + (void)poseAsClass:(Class)aClass 슈퍼 클래스를 교체합니다. Apple은 다음과 같이 씁니다.

포즈 클래스에 의해 정의 된 메소드는 메시지를 통해 super, 상체하는 슈퍼 클래스 메소드를 통합하십시오.

애플이 더 이상 사용되지 않았다 poseAsClass: Mac OS X 10.5에서.

다른 팁

이 클래스에 대해 코딩 할 경우, 선택기의 이름을 코드로 사용할 수있는 것으로 바꾸고 Original Selector에게 전화하십시오. self:

@implementation SampleClass (filePathResolver)
-(NSString*) myFullPathFromRelativePath:(NSString*) relPath
{
    NSString *result = [self fullPathFromRelativePath: relPath];

  ... do some stuff with the old result

    return result;
}

해당 클래스 의이 선택기의 기본 구현을 무시하려면 방법 스위 즈 링 접근하다.

카테고리는 정확히 아니지만 런타임에 동적으로 메소드를 추가하여 해결 방법이 있습니다. 그의 기사에서 Samuel Défago는 Super를 호출하는 블록 임프 구현을 만드는 깔끔한 방법을 설명합니다. 그의 원래 기사를 찾을 수 있습니다. 여기

관련 코드는 다음과 같습니다.

#import <objc/runtime.h>
#import <objc/message.h>

    const char *types = method_getTypeEncoding(class_getInstanceMethod(clazz, selector));
    class_addMethod(clazz, selector, imp_implementationWithBlock(^(__unsafe_unretained id self, va_list argp) {
        struct objc_super super = {
            .receiver = self,
            .super_class = class_getSuperclass(clazz)
        };

        id (*objc_msgSendSuper_typed)(struct objc_super *, SEL, va_list) = (void *)&objc_msgSendSuper;
        return objc_msgSendSuper_typed(&super, selector, argp);
    }), types);
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top