2011-10-20 2 views
0

저는 IOS 프로그래밍에 익숙하지 않지만 하루 이상 지속되어 해결책을 찾을 수없는 문제가 있습니다. 설치 후 첫 번째 실행시 일부 콘텐츠를 다운로드해야하는 앱이 있습니다. 다운로드가 완료되면 RootView 컨트롤러 인 View가 뷰의 데이터를 새로 고치지 않습니다. 올바르게 채워지지만 다른 뷰는 탐색 할 수 있지만이 뷰는 그렇지 않습니다. 내가 응용 프로그램을 닫고 다시 열면 데이터가 나타납니다. 그래서보기를 완전히 다시로드하거나 응용 프로그램을 다시 시작하는 방법이 필요합니다.RootView 컨트롤러를 다시로드하거나 응용 프로그램을 다시 시작하십시오.

#import <UIKit/UIKit.h> 

#import <CoreData/CoreData.h> 

@interface RootViewController : UIViewController <NSFetchedResultsControllerDelegate>{ 

} 
@property (nonatomic, retain) IBOutlet UIImageView *bannerImageView; 
@property (nonatomic, retain) NSFetchedResultsController *fetchedResultsController; 
@property (nonatomic, retain) NSManagedObjectContext *managedObjectContext; 
-(void)populateBannerImages; 
-(void)getimage; 

는 여기에 내가 아래 코드 샘플 응용 프로그램 위임의 다운로드 기능에 대한 대화 상자를 실행 내하는 .m 파일

@implementation RootViewController 
@end 
- (void)viewDidLoad 
    { 
    [super viewDidLoad]; 
    [email protected]"MyTitle"; 

} 
- (void)viewWillAppear:(BOOL)animated 
{ 

    [super viewWillAppear:animated]; 

    } 

    - (void)viewDidAppear:(BOOL)animated 
    { 
     [super viewDidAppear:animated]; 
    } 

    - (void)viewWillDisappear:(BOOL)animated 
    { 
     [super viewWillDisappear:animated]; 
    } 

    - (void)viewDidDisappear:(BOOL)animated 
    { 
     [super viewDidDisappear:animated]; 
    } 
    - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 
    { 
     return [[self.fetchedResultsController sections] count]; 
    } 

    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:           (NSInteger)section 
    { 
     id <NSFetchedResultsSectionInfo> sectionInfo = [[self.fetchedResultsController sections] objectAtIndex:section]; 
     return [sectionInfo numberOfObjects]; 
    } 
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
    { 
     static NSString *CellIdentifier = @"Cell"; 
     UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 
     if (cell == nil) { 
      cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle   reuseIdentifier:CellIdentifier] autorelease]; 
     } 
     [self configureCell:cell atIndexPath:indexPath]; 
     return cell; 
     } 

입니다. 문제는 appDidFinishLAunching에서 UIAlert를 호출하고이 시점에서 rootViewController가 이미로드되었다는 것을 알지만이 작업을 수행하는 데 더 좋은 방법은 아닌 것 같습니다. 그 통지에 등록 모든 뷰 컨트롤러와 NSNotificationCenter를 통해 NSNotification를 파견 :

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions: (NSDictionary *)launchOptions 
{ 
    BOOL hasRunBefore=[[NSUserDefaults standardUserDefaults] boolForKey:@"FirstRun"]; 
    if (hasRunBefore) { 
    }else if(!hasRunBefore){ 
     UIAlertView *firstRunAlert =[[UIAlertView alloc]initWithTitle:@"Welcome" message:@"" delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"DownLoad", nil]; 
     [firstRunAlert show]; 
     [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"FirstRun"]; 
    } 
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{ 
    NSString *buttontitle = [alertView buttonTitleAtIndex:buttonIndex]; 
    if ([buttontitle isEqualToString:@"DownLoad"]) { 
/download stuff here 
    } 
} 

어떤 건설적인 아이디어 나 것 도움을 크게

+0

저장 용량에 핵심 데이터를 사용하는 것 같습니다.핵심 데이터는 강력한 프레임 워크이지만이를 사용하려면 고급 iOS 개발자 여야합니다 (리로드 알림을 구현하는 방법조차 모릅니다) –

+0

예 마틴 (Martin) 저는 의견에 오만함과 냉소의 만지기를 고맙게 생각합니다. 하지만 이미 푸시 알림을 사용하고 있었고 작동하지 않았습니다. 핵심 데이터는 IOS에만 해당되는 것이 아니므로 고급 IOS 개발자가 아니기 때문에 필수적으로 사용해야합니다. ControllerDidChangeContent에서 reloadData가 누락되었습니다. 내가 괜찮다고 덧붙인 후에도 여전히 실질적인 질문에 대답하기 위해 당신의 매력적인 도움이되는 태도 – user1005382

답변

1

코어 데이터 저장 및 페치가 제대로 수행되었다고 가정 할 때 가장 좋은 방법은 NSNotificationCenter를 사용하는 것입니다. AppDelegate 클래스에서 데이터 다운로드가 중단 된 후 알림을 알림 센터에 게시해야합니다. 이 작업은 데이터 다운로드가 완전히 끝난 후에 게시해야합니다. 아마 이런 식으로 뭔가 : 당신의 RootViewController 클래스의 다음

[[NSNotificationCenter defaultCenter] postNotificationName:@"DataFinishedDownloading" 
                object:self]; 

먼저 해당 알림을 청취하기 위해 RootViewController 클래스를 등록해야합니다. 아마 초기화 방법 :

-(id)init 
{ 
    self = [super init]; 
    if(self) 
    { 
     // We add this instance of RootViewController class as an observer of the "DataFinishedDowloading" 
     // Once this notification is posted to the notification center from appDelegate 
     // RootViewController will be notified and the method inside selector will be called 
     [[NSNotificationCenter defaultCenter] addObserver:self 
                selector:@selector(receivedDataFinishedDownloadingNotification:) 
                 name:@"DataFinishedDownloading" 
                object:nil]; 
    } 

    return self; 
} 

- (void)receivedDataFinishedDownloadingNotification:(NSNotification*)notification 
{ 
    // Once the images are done downloading, you just need to refresh the tableView. It will 
    // then display the newly acquired data in your table cells. 
    [tableView reloadData]; 
} 

발생할 수있는 유일한 다른 문제는 (그리고하지 않을 수 있습니다) 데이터 다운로드가 충분히 빨리 발생하는 경우이다. 가끔씩 데이터가 충분히 빠르며 viewController의 viewDidAppear이 아직 발생하지 않은 경우 viewDidAppear이 발생하기 전에 알림 메소드가 reloadData를 시도합니다. 이것은 푸른 달에 한 번 충돌을 일으킬 수 있습니다. 일반적으로 viewDidAppear에서 설정되고 reloadData가 호출되기 전에 확인되는 부울 값은 좋은 생각입니다. 희망이 도움이됩니다.

1
  • 가 다시로드 메커니즘을 만들기 감사합니다. (그런 다음 fetchedResultsController의 인출 요청을 다시 수행하고 [self.tableView reloadData]를 부를 수)
  • 다시로드 루트 뷰 컨트롤러를 : 당신의 앱 위임이 파일을 다운로드 확인하고 새로운 RootViewController를 만들고이 전체보기 (재설정 [self.window setRootViewController:newController]를 호출 => 나쁜 사용자 경험)
+0

+1에 감사드립니다. OP하려면 - 항상 응용 프로그램을 다시 시작하지 않고 수행해야 할 작업이 있다고 가정합니다. – sosborn

0

NSNotificationCenter을 사용하면 과도 할 수 있습니다. NSFetchedResultsController이 있으므로보기 컨트롤러를 대리자로 설정하고 NSFetchedResultsControllerDelegate#controllerDidChangeContent: 메서드를 구현하는 것이 좋습니다.

귀하의 경우 가장 간단한 구현 방법은 [tableView reloadData]입니다. 자세한 내용은 the protocol's docs을 참조하십시오.

관련 문제