2013-04-08 57 views
2

我是新來的iOS編程。檢索圖像形成數據庫的時間過長在iphone

通過使用下面的代碼我從數據庫檢索圖像並將其存儲在數組然後縮略圖顯示這些圖像。

通過使用下面的代碼一切工作正常。但我有2個問題

  1. 從數據庫中檢索圖像花費的時間太長。
  2. 我存儲多於8個圖像意味着它的不顯示圖像時,它將終止application.If我採取以下8圖片其顯示圖像縮略圖。

任何機構可以告訴我,什麼是這個代碼錯誤?

NSString *docsDir; 
NSArray *dirPaths; 

// Get the documents directory 
dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 

docsDir = [dirPaths objectAtIndex:0]; 
array=[[NSMutableArray alloc]init]; 
array1=[[NSMutableArray alloc]init]; 

// Build the path to the database file 
databasePath = [docsDir stringByAppendingPathComponent: @"Taukydataaa.db"]; 

NSFileManager *fn=[NSFileManager defaultManager]; 
NSError *error; 
BOOL success=[fn fileExistsAtPath:databasePath]; 

if(!success) 
{  
    NSString *defaultDBPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"Taukydataaa.db"]; 
    success = [fn copyItemAtPath:defaultDBPath toPath:databasePath error:&error]; 
} 

const char *dbpath = [databasePath UTF8String]; 

sqlite3_stmt *statement; 

if (sqlite3_open(dbpath, &contactDB) == SQLITE_OK) 
{ 
    NSString *querySQL = [NSString stringWithFormat: @"select * from tauky"]; 

    const char *query_stmt = [querySQL UTF8String]; 

    if (sqlite3_prepare_v2(contactDB, query_stmt, -1, &statement, NULL) == SQLITE_OK) 
    { 
     while(sqlite3_step(statement) == SQLITE_ROW) 
     { 

      NSString* email_idField = [[NSString alloc] initWithUTF8String:(const char *) sqlite3_column_text(statement,1)]; 
      NSString* email_idField1 = [[NSString alloc] initWithUTF8String:(const char *) sqlite3_column_text(statement,0)]; 
      [array addObject:email_idField]; 
      [array1 addObject:email_idField1]; 

      blaukypath =[[NSMutableArray alloc]init]; 

      for (NSString* path in array) 
      { 
       [blaukypath addObject:[UIImage imageWithContentsOfFile:path]]; 
      } 

      myScrollView = [[UIScrollView alloc]initWithFrame:CGRectMake(0.0, 0.0, 320.0, 840.0)]; 
      myScrollView.delegate = self; 
      myScrollView.contentSize = CGSizeMake(320.0, 840.0); 
      myScrollView.backgroundColor = [UIColor whiteColor]; 

      [self.view addSubview:myScrollView]; 

      float horizontal = 8.0; 
      float vertical = 8.0; 

      for(int i=0; i<[blaukypath count]; i++) 
      { 
       if((i%4) == 0 && i!=0) 
       { 
        horizontal = 8.0; 
        vertical = vertical + 70.0 + 8.0; 
       } 

       buttonImage = [UIButton buttonWithType:UIButtonTypeCustom]; 

       [buttonImage setFrame:CGRectMake(horizontal, vertical, 70.0, 70.0)]; 
       [buttonImage setTag:i]; 

       [buttonImage setImage:[blaukypath objectAtIndex:i] forState:UIControlStateNormal]; 
       [buttonImage addTarget:self action:@selector(buttonImagePressed:) forControlEvents:UIControlEventTouchUpInside]; 
       [buttonImage setImage:[UIImage imageNamed:@"play.png"] forState:UIControlStateSelected]; 

       [myScrollView addSubview:buttonImage]; 

       horizontal = horizontal + 70.0 + 8.0; 
      } 

      [myScrollView setContentSize:CGSizeMake(320.0, vertical + 78.0)]; 

      // Do any additional setup after loading the view, typically from a nib. 
      self.navigationItem.leftBarButtonItem = self.editButtonItem; 

      UIBarButtonItem *done = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(insertNewObject:)]; 

      self.navigationItem.rightBarButtonItem = done; 

      [self.myScrollView addSubview:image]; 
     } 

     sqlite3_finalize(statement); 
    } 

    sqlite3_close(contactDB); 
} 
+0

將圖像路徑存儲在數據庫中。 – Aslam 2013-04-08 12:53:50

+0

可能有兩種可能的崩潰。文件未找到或內存不足。您是否收到異常代碼和/或錯誤消息? – Rob 2013-04-08 19:03:20

回答

1

一對夫婦的意見:

  • 你把你的,你是從你的表中讀取數據的循環內的滾動型的建築。例如,如果您的數據庫中有九行,則會有9個滾動視圖,第一個包含一個圖像,第二個包含兩個圖像,第三個包含三個圖像,總共包含45個圖像。我真的懷疑這就是你的意思。

  • 你應該有一個從數據庫讀取字符串的循環(做而不是在這一點上創建圖像......只是存儲圖像路徑)並填充你的數組。然後你可以有一個單獨的循環(理想情況下,一個完全獨立的例程),建立你的用戶界面。你真的應該將數據庫交互與用戶界面隔離開來。而任何由圖像對象數組組成的問題都將是有問題的:只維護圖像路徑數組。

這個問題,創造大量的圖像,你不需要,肯定會減慢應用程序和消耗內存。根據圖像的大小,您甚至可能會耗盡內存並崩潰。

在最起碼,你應該解決這個問題。

有一對夫婦的其他問題:

  • 崩潰的另一個潛在來源是,如果你的數組中的圖像路徑之一本身沒有解決到圖像的路徑。因此,imageWithContentsOfFile將返回nil,並且任何嘗試將nil添加到數組都會崩潰。確保在嘗試使用它之前測試以查看是否成功找到/加載了該映像。

  • 你沒有說圖像有多大,但是如果它們大於140x140,你真的想考慮創建它們的屏幕分辨率。如果圖像非常大,而它可以渲染成70x70的圖像,那麼您會用完整圖像的內存。在同時顯示多幅圖像時,如果不小心使用屏幕分辨率圖像,您將很快消耗內存。

  • 根據您的陣列中的多少圖像引用,你甚至可以考慮在那裏你處理UIScrollViewDelegate方法scrollViewDidScroll只有創造UIImageView對象,併爲他們滾動到視圖填充它們各自的image特性的模型(並刪除那些已滾動出視圖)。如果以iOS 6爲目標,則可以使用UICollectionView而不是手動生成的滾動視圖,並且會自動獲得一些功能(只要您的數組是圖像路徑的數組而不是圖像對象的數組)。

如果你還在崩潰,你應該與我們分享崩潰的細節(如果你不告訴我們什麼樣的異常/錯誤你得到的,我們只是猜測)。另外,如果還沒有,請實施didReceiveMemoryWarning,如果沒有其他信息,它會告訴您何時有內存警告,以便您可以確定問題並解決問題。並確保在設備上測試像這樣的內存飢餓的應用程序,因爲有許多內存相關的問題不會在模擬器上顯現,但會在設備上後退。


儘管上述重點討論了崩潰問題,但您還會問一個性能問題。特別是如果你不使用UICollectionView,而是你手動建立你的滾動視圖,那麼你可能想異步做到這一點。基本的想法是,你將有一個後臺操作,將創建UIImage對象,然後派發UI任務將其添加到主隊列中的滾動視圖(因爲你從來沒有做UI後臺隊列中的東西) 。這樣,雖然,用戶可以開始使用應用程序,而圖像彈出到位。

有幾個細微的問題你可能想在這裏考慮(在多線程上做數據庫交互需要一些仔細的實現;確保UI更新發生在主隊列上;等等),但是如果你仍然有性能問題,這是典型的解決方案。

不過,我會專注於先修復崩潰,然後再處理性能問題。

相關問題