0

나는 객관적으로 C를 처음 접했으니, 나와 함께 곰. Xcode4의 유니버설 앱 템플릿으로 시작하여 내 애플리케이션을 구축했습니다. 템플리트가 내가 고집하려고했던 것과 함께 시작한다는 관습이 있습니다. 각 View Controller에는 각 장치 유형에 대한 기본 파일과 하위 클래스가 있습니다. 예 :범용 앱에서 장치 별보기 컨트롤러를 인스턴스화하는 올바른 패턴은 무엇입니까?

Project/ 
    ExampleViewController.(h|m) 
    - iPhone/ 
     - ExampleViewController_iPhone.(h|m|xib) 
    - iPad/ 
     - ExampleViewController_iPad.(h|m|xib) 

대부분이 부분은 매우 편리합니다. 대부분의 로직은 수퍼 클래스에 들어가고 서브 클래스는 모든 장치 특정 구현을 처리합니다.

는 여기에 내가하지 않는 부분입니다. 때로는 각 장치마다 다른 xib를로드해야하기 때문에 각 서브 클래스에서 과 동일한 코드를 사용하는 코드가 있습니다. 예를 들어 :

ExampleViewController_iPhone

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    Content *selectedContent = (Content *)[[self fetchedResultsController] objectAtIndexPath:indexPath]; 
    ContentDetailViewController_iPhone *detailViewController = [[ContentDetailViewController_iPhone alloc] init]; 
    detailViewController.content = selectedContent; 
    detailViewController.managedObjectContext = self.managedObjectContext; 

    [self.navigationController pushViewController:detailViewController animated:YES]; 
    [detailViewController release]; 
} 

ExampleViewController_iPad

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    Content *selectedContent = (Content *)[[self fetchedResultsController] objectAtIndexPath:indexPath]; 
    ContentDetailViewController_iPad *detailViewController = [[ContentDetailViewController_iPad alloc] init]; 
    detailViewController.content = selectedContent; 
    detailViewController.managedObjectContext = self.managedObjectContext; 

    [self.navigationController pushViewController:detailViewController animated:YES]; 
    [detailViewController release]; 
} 

... 그 두 번째 인스턴스에서 다른 유일한 것은이보기 컨트롤러의 _iPad 버전을로드라는 것이다 알 수 있습니다. 이는 iPadiPhone보기 컨트롤러가 별도의 장치 지정 펜촉에 연결되어 있기 때문에 필요합니다.

이 일에 대해 "올바른"패턴이 무엇입니까?


UPDATE

나는 그것이 내가 하나 개의 장치에 대해 특정 서브 클래스를 필요로하지 않는 경우에 도움이 될 것 같아 장치 수식을 사용하여 별도의 xibs의 로딩 this answer를 발견,하지만 여전히 원 특정 장치 기능을위한 특정 뷰 컨트롤러 인스턴스 인 _iPhone 또는 _iPad 인스턴스를 생성해야하는 경우 도움이됩니다. 문제를 해결하기 위해 두 가지 간단한 방법이

답변

1

있습니다. 당신의 수퍼 클래스에 둘 때 모두 작동합니다.

첫 번째 방법은 두 개의 서로 다른 클래스를 가지고 있기 때문에 작동하고, 어느 것이 생성 장치가 사용에 따라 달라집니다. 장치 별 코드가 없기 때문에 다른 클래스를 사용하지 않으면 이 작동하지 않습니다. 그것은 그것이 무엇인지 결정하기 위해 객체를 요청합니다. 객체의 클래스는 수퍼 클래스가 요청할 때에도 디바이스 고유의 클래스가되므로 생성 된 클래스를 확인하고 그에 따라 행동 할 수 있습니다.

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    Content *selectedContent = (Content *)[[self fetchedResultsController] objectAtIndexPath:indexPath]; 
    Class classToUse; 
    if([self class] == [ExampleViewController_iPad class]) { 
     // We are running on the iPad 
     classToUse = [ContentDetailViewController_iPad class]; 
    } else { 
     // We must be running on either the iPhone or iPod touch 
     classToUse = [ContentDetailViewController_iPhone class]; 
    } 
    // Just use superclass for typing here, since we aren't doing anything device specific 
    ContentDetailViewController *detailViewController = [[classToUse alloc] init]; 
    detailViewController.content = selectedContent; 
    detailViewController.managedObjectContext = self.managedObjectContext; 

    [self.navigationController pushViewController:detailViewController animated:YES]; 
    [detailViewController release]; 
} 

두 번째 방법은 프로그램의 모든 위치에서 작동합니다. Apple은 iOS 3.2의 UIDevice 클래스에 "user interface idiom"이라는 속성을 추가했습니다. 현재 가능한 값은 UIUserInterfaceIdiomPadUIUserInterfaceIdiomPhone입니다. 이 3.2 이전 버전에 존재하지 않기 때문에, 애플은 또한보다 크거나 3.2 동일한 경우 UIDevice 개체에서 실제 값을 버전이 3.2보다 작은 경우 UIUserInterfaceIdiomPhone을 반환하고 얻을 것이다 매크로를 추가했다. 우아한 단순하고 잘 설명 솔루션

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    Content *selectedContent = (Content *)[[self fetchedResultsController] objectAtIndexPath:indexPath]; 
    Class classToUse; 
    // If you aren't supporting versions prior to 3.2, you can use [UIDevice currentDevice].userInterfaceIdiom instead to save a couple of cycles 
    if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) { 
     // We are running on the iPad 
     classToUse = [ContentDetailViewController_iPad class]; 
    } else { 
     // We must be running on either the iPhone or iPod touch 
     classToUse = [ContentDetailViewController_iPhone class]; 
    } 
    // Just use superclass for typing here, since we aren't doing anything device specific 
    ContentDetailViewController *detailViewController = [[classToUse alloc] init]; 
    detailViewController.content = selectedContent; 
    detailViewController.managedObjectContext = self.managedObjectContext; 

    [self.navigationController pushViewController:detailViewController animated:YES]; 
    [detailViewController release]; 
} 
+0

+1. 정확히 내가 필요로하는 것.나중에 Objective C에서 사용하기 위해 클래스 참조를 저장할 수 있다는 것을 알지 못해서 예제가 특히 유용했습니다. 감사! – markquezada