2011-02-25 101 views
1

好吧,這是一個非常奇怪的,所以我要佈局正在發生的事情,然後給一些代碼。在我的例子,我將使用的意見靜態量,2UITableView reloadData導致所有的動畫停止工作

基礎知識
我有X一UIPageControl許多子視圖添加。在每個子視圖上,viewDidLoad是一個NSXMLParse來獲取XML提要。一旦獲得提要,就會解析並使用解析的數組重新加載表。每個視圖上還有一個設置按鈕。當按下設置按鈕時,運行UIModalTransitionStyleCoverVertical:Animated:YES,並將UINavigationController向上滑動到具有完整動畫的視圖中。關閉還顯示動畫滑出回到先前的視圖。如果您處於「設置」中,則可以將PushViews深入兩層(幻燈片放入動畫)。

的問題
的一個隨機時間,當應用程序是建立和運行(未恢復)當你點擊設置按鈕,不會發生動畫。除了所有核心動畫被刪除之外,一切都是有效的。 DismissModal只需交換回前一個屏幕。 NavigationController中的PushView不再有任何動畫,下一個視圖就會出現。

如果您退出應用程序(殺死進程)並重新啓動它,它可能會在一段時間內正常工作,但在點擊設置按鈕的某個時刻,它會丟失所有動畫。

詳細信息
我從蘋果的PageControl應用程序開始的基礎。它根據用戶設置創建動態數量的視圖。

- (void)awakeFromNib 
{ 
    kNumberOfPages = 2; 

    // view controllers are created lazily 
    // in the meantime, load the array with placeholders which will be replaced on demand 
    NSMutableArray *controllers = [[NSMutableArray alloc] init]; 
    for (int i = 0; i < kNumberOfPages; i++) 
    { 
     [controllers addObject:[NSNull null]]; 
    } 

    self.viewControllers = controllers; 

    // a page is the width of the scroll view 
    scrollView.pagingEnabled = YES; 
    scrollView.contentSize = CGSizeMake(scrollView.frame.size.width * kNumberOfPages, scrollView.frame.size.height); 
    scrollView.showsHorizontalScrollIndicator = NO; 
    scrollView.showsVerticalScrollIndicator = NO; 
    scrollView.scrollsToTop = NO; 
    scrollView.delegate = self; 

    pageControl.numberOfPages = kNumberOfPages; 
    pageControl.currentPage = 0; 

    // pages are created on demand 
    // load the visible page 
    // load the page on either side to avoid flashes when the user starts scrolling 
    [self loadScrollViewWithPage:0]; 
    [self loadScrollViewWithPage:1]; 
} 


- (void)loadScrollViewWithPage:(int)page 
{ 
    if (page < 0) 
     return; 
    if (page >= kNumberOfPages) 
     return; 

    // replace the placeholder if necessary 
    SecondViewController *controller = [viewControllers objectAtIndex:page]; 
    if ((NSNull *)controller == [NSNull null]) 
    { 
     controller = [[SecondViewController alloc] initWithPageNumber:page]; 
     [viewControllers replaceObjectAtIndex:page withObject:controller]; 
     [controller release]; 
    } 

    // add the controller's view to the scroll view 
    if (controller.view.superview == nil) 
    { 
     CGRect frame = scrollView.frame; 
     frame.origin.x = frame.size.width * page; 
     frame.origin.y = 0; 
     controller.view.frame = frame; 
     [scrollView addSubview:controller.view]; 
    } 

} 

如產生的每個視圖,它運行一個NSXMLParse在其viewDidLoad。到目前爲止,一切正常。這兩個視圖都會生成,您可以在它們之間滑動。

如果按下設置按鈕

- (IBAction)settingsButtonPressed:(id)sender; 
{ 
    SettingsViewController *settingsViewController = [[SettingsViewController alloc] initWithNibName:@"SettingsViewController" bundle:nil]; 

    UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:settingsViewController]; 

    navigationController.modalTransitionStyle = UIModalTransitionStyleCoverVertical; 

    [self presentModalViewController:navigationController animated:YES]; 

    [settingsViewController release]; 
    [navigationController release]; 
} 

在這一點上,SettingsViewController似乎進入視野。但是,有時它會以適當的動畫向上滑動。其他時候,它只會出現,所有進一步的核心動畫都會被打破,直到重新啓動進程。

我檢查了所有NSXMLParse,並將問題縮小到一行。在我的每個子視圖中,是一個tableView,在XML解析完成後,我創建了一個包含結果的數組,並運行[self.tableview reloadData]。如果我註釋掉這一行,表格顯然只會加載空白,但它與動畫沒有任何問題。

- (void)parserDidEndDocument:(NSXMLParser *)parser 
{ 
    NSMutableArray *tableData = ARRAY_GENERATED_HERE; 
    [self.tableView reloadData]; 
} 

我的測試
我會從我的測試中注意,如果kNumberOfPages設置爲1,而不是2,只有1視圖獲取產生的一切都很好,從來沒有出現毛刺動畫。添加第二個視圖,通常在打開設置五次內,它會產生小故障。

還沒有找到解決辦法,但它與[tableView reloadData]有關。任何見解都會很棒。

Daniel指出了一些有意義的東西。使用

我的XML是在viewDidLoad中獲取:

[NSThread detachNewThreadSelector:@selector(parseXMLFileAtURL:) toTarget:self withObject:path]; 

- (void)parseXMLFileAtURL:(NSString *)URL 
{ 
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 

    stories = [[NSMutableArray alloc] init]; 

    //you must then convert the path to a proper NSURL or it won't work 
    NSURL *xmlURL = [NSURL URLWithString:URL]; 

    // here, for some reason you have to use NSClassFromString when trying to alloc NSXMLParser, otherwise you will get an object not found error 
    // this may be necessary only for the toolchain 
    rssParser = [[NSXMLParser alloc] initWithContentsOfURL:xmlURL]; 

    // Set self as the delegate of the parser so that it will receive the parser delegate methods callbacks. 
    [rssParser setDelegate:self]; 

    // Depending on the XML document you're parsing, you may want to enable these features of NSXMLParser. 
    [rssParser setShouldProcessNamespaces:NO]; 
    [rssParser setShouldReportNamespacePrefixes:NO]; 
    [rssParser setShouldResolveExternalEntities:NO]; 

    [rssParser parse]; 

    [pool release]; 
} 
+0

是在後臺線程parseDidEndDocument出現?因爲它是...因爲用戶界面不是線程安全的...也許你的問題,你正在後臺(不安全)進行UI套件調用,並在主線程中動畫...(行爲未定義) – Daniel 2011-02-25 20:03:48

+0

@Daniel - 你實際上可能會在這裏的東西。我將XML請求作爲分離線程運行。我將更新主要問題,並在「我的測試」標題下爲其底部添加一些額外內容。 – 2011-02-25 20:09:48

+0

如果你這樣做,那麼這是你的問題... UIKit不是線程安全的...嘗試在主線程中執行重新加載調用 – Daniel 2011-02-25 20:11:21

回答

2

從你的評論,你說你在後臺線程中運行解析器... UIKit的不是線程安全的,我懷疑是什麼引起你的問題......請嘗試在主線程中調用reloadData,您可以使用NSObjects performSelectorInMainThread做到這一點...

[self performSelectorOnMainThread:@selector(operationComplete) withObject:nil waitUntilDone:false]; 
+0

剛剛實現此操作,進入和退出設置菜單幾十次後尚未發生。看起來這個問題現在已經解決了。謝謝! – 2011-02-25 20:21:48

+0

是的,只記得UIKit不是線程安全的;) – Daniel 2011-02-25 20:22:54

+1

取決於我們正在討論的iOS版本。 UIKit在iOS 4.0+中是線程安全的。 – bstahlhood 2011-03-01 05:56:23