2014-02-24 2 views
1

iOS 7 용 프로그램을 만들고 있지만 몇 가지보기에서 거의 동일한 메서드를 사용하므로 대부분의 메서드와 메서드를 다루는 공통 클래스를 만들고 싶습니다. 모든보기에 대해 개별적인 마무리 터치에 콜백 메소드를 사용합니다. 다음과 같은Objective-C 다른 클래스의 인수로 콜백 메서드

#import <Foundation/Foundation.h> 

@interface Common : NSObject 

+(void)target:(Class)object method:(SEL)selector; 

@end 

Common.m됩니다 : 런타임에

+(void)target:(Class)object method:(SEL)selector 
{ 
    NSLog(@"target..."); 
    if ([object respondsToSelector:@selector(selector)]) 
    { 
     [object performSelector:@selector(selector)]; 
    } else { 
     NSLog(@"%@", object); 
    } 
} 

는,

// On top of the view .m 
#import "Common.h" 

// Method which will be called. 
-(void)doSomething 
{ 
    NSLog(@"doSomething..."); 

    [Common target:self method:@selector(callbackMethod)]; 
} 

// Method I want to be called. 
+(void)callbackMethod 
{ 
    NSLog(@"Should come here..."); 
} 

Common.h은 다음과 같습니다 : 내가보기에 다음 코드를 출력 만 : doSomething ..., 대상 ..., < 부모보기 컨트롤러 : 0x8d24bb0 >

여기서 문제는 콜백 메소드를 호출하는 것입니다. 프로그램은 Common.m의 메소드에 도달하지만 부모로부터 메소드를 호출 할 수 없습니다.

+0

슈퍼 클래스) 모든 공통 비트를 구현합니다. 그런 다음 해당 클래스의 하위 클래스를 만들고 사용자 정의해야하는 메서드를 무시할 수 있습니다. 'performSelector'는 항상 이상한 냄새가납니다. 또는 공통 비트에 대해 클래스 범주를 사용하십시오. – verec

+0

@selector()는 SEL 개체를 만드는 데 사용되는 리터럴입니다. SEL을 전달했기 때문에 @selector()를 사용하여 해당 인수를 래핑 할 필요는 없습니다. 직접 사용할 수도 있습니다. –

답변

2

문제는 그라는 방법

@selector(selector) 

검색 "선택기." @selector()은 괄호 안에 이름이 포함 된 선택기를 검색합니다.

전달하려는 선택기를 사용하려면 원하는 항목을 가져 오지 말고 다른 항목을 가져와야합니다. 당신은 당신이 다른 모든 변수와 선택 방법에 전달하여 다음을 수행하십시오 ARC 시스템은 무슨 일이 일어나고 있는지 알 수 없기 때문에

+(void)target:(Class)object method:(SEL)selector 
{ 
    NSLog(@"target..."); 
    if ([object respondsToSelector:selector]) 
    { 
     [object performSelector:selector]; 
    } else { 
     NSLog(@"%@", object); 
    } 
} 

ARC를 사용하여이 경고의 원인이됩니다. 컴파일러에게 performSelector:을 의도적으로 호출했음을 알리고 누출이 없음을 알리기 위해이 한 줄만 경고를 해제 할 수 있습니다. 누출이 전혀 확실하지 않은 경우에만이 작업을 수행하십시오.

#pragma clang diagnostic push 
#pragma clang diagnostic ignored "-Warc-performSelector-leaks" 
      [object performSelector:selector]; 
#pragma clang diagnostic pop 

마지막으로,의, 당신의 선택에 callbackMethod을 살펴 보자 : 이것은 선택에 응답하지 않는 따라서 클래스의 당신의 예를 클래스 메소드가 아닌 인스턴스 방법이다

+(void)callbackMethod 
{ 
    NSLog(@"Should come here..."); 
} 

, 반면 클래스 자체 않습니다. 클래스 메소드에서 인스턴스 메소드로 변경하면 ('+'를 '-'로 바꿈)이 문제를 해결할 수 있습니다.

-(void)callbackMethod 
{ 
    NSLog(@"Should come here..."); 
} 
+0

다음 경고 메시지가 표시됩니다. _PerformSelector는 선택기가 unknown_이므로 누수가 발생할 수 있습니다. 경고 외에도 여전히 콜백 메소드를 입력하지 않습니다. 다른 아이디어? '- doSomething'에 – Sietse

+1

이 있으면 * 인스턴스 *를 참조하는'self'를 전달합니다. 그러나'+ target'에서 매개 변수를'(id)'가 아닌'(Class)'로 문서화합니다.그리고 인스턴스 메소드 selector를 클래스 메소드 selector로 보내고 싶어하는 것처럼 보입니다.'+ callbackMethod'는 _instance_ 메소드가 아닌 _class_ 메소드입니다. 그러나이 전체 코드는 실제로 냄새가 ... – verec

+0

나는 그 문제를 놓친, 나는 대답을 업데이 트했습니다. 또한 @verec에 동의합니다. ObjC의 기능을 실험하기위한 코드라면 괜찮습니다.하지만 프로덕션 코드로 만들려면 매우 냄새가납니다. 리팩터링 할 필요가있는 간접적 인 계층이 너무 많습니다. – BergQuester