2014-06-16 1 views
3

사용자 클래스를 내 클래스에 추가했는데 prepareForSegue : 메서드 중에 대리자를 설정하려고하면 컴파일러 경고가 표시됩니다. 내가 얻는 경고는 ...사용자 지정 프로토콜에 대한 위임을 설정하는 경고가 발생합니다.

Sending 'MyCustomViewControllerClass *const __strong' to parameter of incompatible type 'id<NSFileManagerDelegate>' 

프로젝트가 빌드되어 실행되고 모든 것이 경고에서 마이너스 경고를 뺀다. 내 맞춤 클래스에 <NSFileManagerDelegate>을 추가하면 경고가 사라집니다. 내가 누락 된 것이 있거나 Xcode (6 베타)의 버그입니까? 코드가

SomeSecondClass.h

#import <UIKit/UIKit> 

@class SomeSecondCustomViewController; 

@protocol SomeSecondCustomViewControllerDelegate <NSObject> 
- (void)doThisForMe 
@end 

@interface SomeSecondCustomViewController : UIViewController 

@property (weak, nonatomic) id <SomeSecondCustomViewControllerDelegate> delegate; 

@end 

SomeSecondClass.m ... 프로토콜/대리자를 설정하지만 난 어쨌든 그것을 게시 할 예정 표준 코드입니다

@interface SomeSecondViewController() 
…stuff 

-(void)someMethod { 

    [self.delegate doThisForMe]; 
} 

@end 

CustomClass.h

#import <UIKit/UIKit.h> 
#import “ SomeSecondViewController.h” 

@interface MyCustomViewController : UIViewController <SomeSecondCustomViewControllerDelegate> 
//adding on <NSFileManagerDelegate> removes the warning... 
@end 

CustomClass.h

...standard stuff... 

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender 
{ 
    if ([[segue identifier] isEqualToString:@"MySegue"]) { 

     //this is where the warning happens on "self" 
     [segue.destinationViewController setDelegate:self]; 

    } 
} 


- (void)doThisForMe { 

    //doing some stuff... 

} 
@end 

경고가 존재하지 않는 이전 프로젝트가 열렸으며 동일한 경고가 나타납니다. 이 Xcode 문제가 궁금해?

답변

12

을 당신은 오브젝티브 C가 일치하는 선택기를 찾는 방법에 모호함으로 인한 문제로 실행하고 id 참조 다루고있다 .

UIStoryboardSegue destinationViewControllerid을 반환합니다. 그런 다음 코드에서이 id 참조에 대해 setDelegate 메소드를 호출하려고합니다. 이 id이 실제로 무엇을 참조하는지에 대한 정보가 없으므로 어떤 의미 일 수 있는지 알 수 없습니다 (많음). 그래서 컴파일러는 알고있는 목록을 스캔하여 하나를 선택합니다. 이 경우 NSFileManager 클래스에서 setDelegate: 메서드를 선택했습니다. selfNSFileManagerDelegate 프로토콜을 따르지 않으므로 경고 메시지가 표시됩니다.

경고를 무시할 수 있으며이 경우 코드가 정상적으로 작동합니다.

더 나은 솔루션은 캐스트를 추가하여 컴파일러를하는 것입니다 :

[(SomeSecondCustomViewController *)segue.destinationViewController setDelegate:self]; 

이 컴파일러는 당신이 정말로 의미하는 setDelegate: 방법을 알려줍니다.

BTW - NSFileManagerDelegate을 수업에 추가하는 것이 현재로서는 효과가 있지만 유효한 해결책은 아닙니다. 일부 import 문을 단순하게 재정렬하면 컴파일러가 다른 선택을하도록 유도 할 수 있으며 경고는 반환되지만 다른 프로토콜을 준수하지 않는다고 불평 할 수 있습니다.

+0

그냥 감추고있는 사람을 위해, 이것은 Swift 호환성을위한 Xcode 6의 컴파일러 변경입니다. 앞으로 나아갈 Swift는 델리게이트 설정을위한 "유형"을 기대합니다. 이것은 위에서 언급 한 것처럼 캐스팅과 동일합니다. 내 생각에 경고가 Xcode 6에서만 발생하는 이유가 여기에 있습니다. – DoS

0

이처럼 destinationVC을 (에 형식을 부여)를 입력 명시 적으로 시도해보십시오

SomeSecondCustomViewController *vc = (SomeSecondCustomViewController *)segue.destinationViewController; 
vc.delegate = self; 
+0

나는 경고를 제거하지만 prepareForSegue 동안 불필요한 단계 여야한다. 이미 프로세스가 완료되었으므로. 나는 Xcode 5에서이 오류를 얻지 못했지만 전에 루프를 던지고있다. – DoS

1

이 내용은 Xcode 6 베타의 버그/변경 내용입니다. Xcode 5.1.1에서 똑같은 코드를 실행하면 경고 나 오류가 발생하지 않습니다.문제는 Xcode 6에서 컴파일러가 형식을 요구하기 때문에 발생합니다.

(id<NSFileManager>) 

대리인 용입니다. Xcode 5.1에서는 컴파일러가 간단하게 예상하고 있습니다.

(id) 

(대리자 형식) rmaddy로

는 경고를 제거했다

[(SomeSecondCustomViewController *)segue.destinationViewController setDelegate:self]; 

의 유형을 주조로, 진술, 그러나 이것은 불필요한 단계를해야하며, 엑스 코드에 문제가 그것을 분필 것입니다.

0

@rmaddy가 정답을 제공합니다. 이것은 Objective-C의 방식으로 가볍게 교육받은 우리들을위한보다 상세한 예입니다.

[[segue destinationViewController] setDelegate:self]; 
    UIPopoverController *popoverController = [(UIStoryboardPopoverSegue *)segue popoverController]; 
    self.flipsidePopoverController = popoverController; 
    popoverController.delegate = self; 

에 :

나는에서 내 코드를 변경

[(UIPopoverController *)segue.destinationViewController setDelegate:self]; 
    UIPopoverController *popoverController = [(UIStoryboardPopoverSegue *)segue popoverController]; 
    self.flipsidePopoverController = popoverController; 
    popoverController.delegate = self; 

와 경고는 사라졌다.

관련 문제