2012-09-29 2 views
2

는 내가이 프로젝트를 상속하고 무슨 일이 일어나고 있는지 확실하지 않은 한 다음과 같은 오류Obj-C, 'navigationController'속성이 NSObject 클래스의 유형 객체에 없습니다.

Property 'navigationController' not found on object of type 

을 얻고있다. 내가 아울렛 있었다 애플 대리자 네비게이션 컨트롤러에 액세스되면서 didSelectRowAtIndexPath 내 m 파일에서

내가

[self.navigationController pushViewController:nextController animated:YES]; 

이이 문제가 전에하지 않았다. 그러나, 나는이 접근법에서 벗어나면 문제를 야기했다. 나는 나머지 프로젝트를 개조했다. 그러나 프로젝트가 정상적인 테이블 뷰를 사용하지 않는이 상황에서는 내비게이션 컨트롤러가 사용 가능한 것으로 보이지 않습니다. 7 가지 다른 견해에서이 문제가 있습니다. 이 문제를 해결하고 더 깨끗한 코드를 유지할 수 있었으면 좋겠습니까?

enter image description here 저는 이것이 실제로 당황 스럽습니다. SetsStyleSectionController는 뷰 컨트롤러가 아니지만 NSObject 인 것으로 생각됩니다.

그러나 UIViewController로 설정된 경우에도 코드는 실행되지만 그 중 하나를 누르지 않습니다. SetsContectionController를 NSObject에서 UIViewController로 변경할 수 없습니다.

진행 방법이 확실하지 않습니다.

저는 앱 대리인을 밀어내는 과정에서 멀어지고 있습니다.

편집 : 스크린 샷 2는 여기 문제의 몇 가지를 볼 enter image description here

+1

프로젝트에 UINavigationController가 설치되어 있습니까? –

+0

예 및 tabbarcontroller. 이 클래스는 테이블 뷰를 생성하기 위해 클리너를 사용하도록 설계되었습니다. – Jules

+1

왜'SetsSectionController' 대신'UITableViewDelegate'를 사용하지 않습니까? 무엇을 의미합니까 "SetsSectionController를 NSObject에서 UIViewController로 변경할 수 없습니다"? 'SetsStyleSectionController'는 'navigationController'라는 속성을 가지고 있습니까? –

답변

1

아래 논의했다. 당신은 프로토콜과 클래스에 대한 오해를 가지고 있습니다. 그리고 당신은 선의로 실제로 인생을 힘들게 만드는 프로토콜과 인터페이스하는 어플리케이션을 가지고 있습니다.

첫 번째 문제는 프로토콜과 클래스의 차이를 파악하고 프로토콜을 채택하고 클래스를 상속하는 것입니다. 어느 것이 완전히 괜찮습니까,이 물건은 쉽지 않습니다. 기본적으로 프로토콜은 객체에 대한 인터페이스 일 뿐이며 클래스는 인터페이스와 구현을 모두 제공합니다. 즉, 프로토콜은 호출 할 수있는 메소드 목록 일 뿐이며 클래스는 메소드 목록과 해당 메소드를 실행하는 코드입니다. 보다 완전한 설명을 얻으려면 아마도 소스 코드로 바로가는 편이 낫습니다. Apple의 "The Objective-C Programming Language"이 도움이 될 것입니다. 따라서 클래스와 프로토콜에 대해 읽어보십시오. 나는 당신이 왜 id<SetSectionController> 인스턴스에 navigationController 속성을 명시 적으로 정의하지 않고 성공하지 못하는지 알게되었다고 생각합니다. 나중에 이에 대해 구체적인 질문이 있으면 알려 주시기 바랍니다.

수정하기가 어려운이 SetSectionController 프로토콜입니다. 몇 가지 문제가 있으며이 문제를 모두 설명하는 것이이 답변의 범위를 벗어납니다. 구현은 기본적으로이 프로토콜을 구현하는 객체가 어떤 네비게이션 컨트롤러가 테이블 뷰와 관련되어 있는지를 요구합니다. 지금까지 deus ex machina을 응용 프로그램의 델리게이트에 연결하여이 커플 링을 제거 할 수 있습니다. 그러나 이제는보기 컨트롤러에 데이터를 채워 탐색 스택에 밀어 넣을 수있는 또 다른 방법을 찾아야합니다.

푸시 로직을 뷰 컨트롤러로 옮기고 섹션 컨트롤러에 필요한 정보를보기 컨트롤러에 제공하는 인터페이스를 제공해야한다고 생각합니다. 그래서 절 컨트롤러가이 의사 등의 구현이 말 :

- (void)...didSelectRow... 
{ 
    id detailsForIndexPath = self.dataForRows[indexPath.row]; 
    DetailViewController *vc = [DetailViewController new]; 
    vc.details = detailsForIndexPath; 
    [APPDELEGATE.navigationController push:vc]; 
} 

가 그럼 난 -dataForRow:처럼 SetSectionController라는 뭔가 방법을 추가 할 것을의 구현은 위의 방법의 첫 번째 줄과 같은 것이다. 그런 다음 뷰 컨트롤러,이 같은 ...didSelectRow...을 구현 :

당신의 섹션 컨트롤러가 지금 뷰 컨트롤러로 옮기거나 섹션 컨트롤러에 ...didSelectRow...을 전달할 중 하나를 확인 ...didSelectRow...에 유용한 다른 작업을 수행하는 경우
- (void)...didSelectRow... 
{ 
    id<SetSectionController> sc = self.sectionControllers[indexPath.section]; 
    id details = [sc dataForRow:indexPath.row]; 
    DetailViewController *vc = [DetailViewController new]; 
    vc.details = details; 
    [self.navigationController push:vc]; 
} 

.

다형성을 통해 복잡한 테이블 섹션을 관리하기가 쉽지만이 프로토콜은 올바른 방법이 아니 었습니다. 그것은 UITableViewDelegateUITableViewDataSource의 메소드를 맹목적으로 복사하는데, 그것들이 단일 테이블의 단일 섹션에 대한 책임을 묻는 올바른 질문인지 아닌지를 고려하지 않습니다. 여전히 그것을 사용하고 싶다면 실제로 더 힘들어지는 것보다 실제로 당신의 삶을 편하게 만드는 모양으로 바꾸기 위해 상당한 리팩토링이 필요하다고 생각합니다. 섹션 당 논리 편차의 복잡성에 따라 전체를 스크랩 할 수 있습니다. 그러나 그것은 정말로 다른 질문입니다. 희망이 도움이!

1

"사용할 수 없음"이란 무엇을 의미합니까? UIViewController의 하위 클래스를 허용하거나 허용하지 않거나 컴파일러 오류가 발생 했습니까? 귀하의 질문에 대한 내 댓글에서 :

SetsSectionController.h:12:34: Cannot find protocol declaration for 'UIViewController'

당신은 당신의 서브 클래스를 변경할 수있는 잘못된 일을 변경하고 있습니다. 예 :

#import <Foundation/Foundation.h> 

@protocol foo <NSObject> 
- (void) bar; 
@end 

@interface lolcats : NSObject <foo> 
@end 

콜론 뒤에 클래스 이름을 변경하려면 다음과 같이하십시오. 전의.

@interface lolcats : NSObject <foo> 

@interface lolcats : UIViewController <foo> 

이되고 당신은 해제하고 실행할 수 있습니다. 실수 프로토콜

@protocol foo <NSObject> 

@protocol foo <UIViewController> 
대신

, 또는 <UIViewController>을 준수 프로토콜을 변경

에 대한 프로토콜 요구 사항을 변경하는 경우에는, 당신은 당신이있어 정확한 오류가 될 겁니다 . 프로토콜은 그것을 준수하는 객체가 NSObject 프로토콜을 준수해야한다는 것을 프로토콜이 나타내므로 혼란 스러울 수 있으며 NSObject 또한 객체의 유형입니다. 객체와 프로토콜은 별도의 객체이며 모든 객체는 NSObject를 상속하므로 프로토콜을 상속받습니다. 기본적으로 "이 프로토콜을 사용하는 객체는 객체 여야합니다."

왜 이것이 효과가 있었습니까? 객체는 몇 가지 메소드가 포함 된 프로토콜을 준수한다는 것을 나타내는 표준 NSObject입니다. 왜 네비게이션 컨트롤러 속성을 가지고 있을까요? 그것을 아무 것도 상속받지 못했습니다. 비용에 관계없이, 귀하의 오류를 기반으로, 당신은 아마 방금 잘못 바꿨습니다. 콜론 다음에 수퍼 클래스 클래스 이름을 변경해야합니다.

+0

프로토콜을 변경하려고 할 때 오류를 포함하여 내 질문에 캡쳐 화면을 추가했습니다. NSObject에서 UIViewController로 인터페이스를 변경하려고합니다. NSObject로 다시 변경하면 모든 것이 실행되지만 밀어 넣기가 작동하지 않고 오류가 발생하지 않습니다. 내가 대답하지 않은 질문이 있는지 확실하지 않습니까? – Jules

+0

@Jules Metabble이 맞습니다. 문제는 "UIViewController"는 프로토콜이 아닌 객체 또는 클래스입니다. 그래서 "프로토콜 선언을 찾을 수 없습니다 ..."오류가 발생합니다 (첫 번째 스크린 샷). "UITableViewDelegate"에는 이미 생성하려는 메서드 정의가 있으므로 "SetsSectionController"프로토콜을 만들지 않아도됩니다. 또한 UITableViewController는 이미 UITableViewDelegate 프로토콜을 준수합니다. SetsSectionController.h 파일을 삭제하고 ""및 SetsStyleSectionController.h 파일에서 가져 오기를 제거하십시오. – RyanM

+0

@Jules 슈퍼 클래스 선언을 프로토콜 요구 사항과 혼동 했습니까? 여러분의 객체는 프로토콜에서 선언 된 몇 가지 추가 메소드를 가진 단순한'NSObject'입니다. 당신이 뭘 기대하는지 모르겠다. 그것은'UIViewController' 또는'UITableViewController' 서브 클래스가 아닙니다. 상속받은 클래스를 변경하려는 것 같지만 잘못된 위치에서 수행하고 있습니다. 원래 "속성을 찾을 수 없음"오류는 사용자 나 참조가있는 객체가 아마도'NSController' 서브 클래스에서 사용할 수없는'navigationController' 속성에 액세스하려고 시도하고 있다는 사실에서 유래합니다. – Metabble

관련 문제