2013-08-16 19 views
1

我在服務器中存儲了一些圖像。我使用JSON從服務器獲取遠程數據。當我在本地數據庫中存儲圖像時,它正在工作。當我使用json url時,它不起作用。我得到EXC_BAD_ACCESS錯誤。圖像沒有從數據庫中提取

代碼:

Mysof.h文件:

@interface Mysof : NSObject{ 
    NSInteger sofaId; 
    NSString *sofa; 
    NSString *rating; 
    UIImage *photo; 
} 

@property (nonatomic,retain)NSString *sofa; 
@property (nonatomic, assign) NSInteger sofaId; 
@property (nonatomic, retain)NSString *rating; 
@property (nonatomic, retain) UIImage *photo; 

@end 

Mysof.m文件:

@implementation Mysof 

@synthesize sofId; 
@synthesize sofa; 
@synthesize rating; 
@synthesize photo; 

@end 

Sofalistsql.h文件:

@interface Sofalistsql : NSObject 

{ 
    sqlite3 *db; 
} 

- (NSMutableArray *) getMysofas; 

@end 

.m文件:

@implementation Sofalistsql 

    - (NSMutableArray *) getMysofas{ 


    NSMutableArray *sofArray = [[NSMutableArray alloc] init]; 

    NSFileManager *fileMgr = [NSFileManager defaultManager]; 
    NSError *err; 

    NSString *bundlePath = [[NSBundle mainBundle] pathForResource:@"Empty" ofType:@"sqlite"]; 
    //NSLog(@"bundlePath %@", bundlePath); 


    //call update function to check any data updated, 
    //if there is a version difference 
    //update the data base with all the required fileds. 



    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES); 
    NSString *documentsDirectory = [paths objectAtIndex:0]; 
    //NSLog(@"docs dir is %@", documentsDirectory); 

    NSString *appFile = [documentsDirectory stringByAppendingPathComponent:@"App6.sqlite"]; 

    [fileMgr copyItemAtPath:bundlePath toPath:appFile error:&err]; 


    NSURL *URL = [NSURL URLWithString:@"http://server.net/projects/mobile/jsonstring.php"]; 

    NSLog(@"URL is %@", URL); 


    NSError *error; 
    NSString *stringFromFileAtURL = [[NSString alloc] 
    initWithContentsOfURL:URL 
    encoding:NSUTF8StringEncoding 
    error:&error]; 

    //NSLog(@"response is %@", stringFromFileAtURL); 

    NSString *path = [documentsDirectory stringByAppendingPathComponent:@"App6.sqlite"]; 


    NSArray *userData = [stringFromFileAtURL JSONValue]; 

    // NSArray *skarray = [[NSArray alloc]init]; 



    NSLog(@"userdata is %@", userData); 

    // int i = 0; 
    BOOL notExist = TRUE; 


    for (NSArray *skarray in userData) { 

    for (NSDictionary *tuser in skarray) { 


      //if already exists in data base id then overwrite the name 

     if (sqlite3_open([path UTF8String], &db) == SQLITE_OK) { 


     const char *sql = [[NSString stringWithFormat:@"SELECT id FROM categories where id = '%@'",[tuser objectForKey:@"id"]] cStringUsingEncoding:NSUTF8StringEncoding];  

    //NSLog(@"check stmt is %s", sql); 

    sqlite3_stmt *sqlStatement,*addStmt; 

    if (sqlite3_prepare_v2(db, sql, -1, &sqlStatement, NULL) == SQLITE_OK) { 

     notExist = TRUE; 

    while (sqlite3_step(sqlStatement) == SQLITE_ROW) { 

     notExist = FALSE; 


    Mysof *Mylist = [[Mysof alloc]init]; 
    Mylist.sofaId = sqlite3_column_int(sqlStatement, 0); 
    Mylist.sofa = [NSString stringWithUTF8String:(char *) sqlite3_column_text(sqlStatement,1)]; 
    Mylist.rating = [NSString stringWithUTF8String:(char *) sqlite3_column_text(sqlStatement, 2)]; 
    const char *raw = sqlite3_column_blob(sqlStatement, 3); 
    int rawLen = sqlite3_column_bytes(sqlStatement, 3); 
    NSData *data = [NSData dataWithBytes:raw length:rawLen]; 
    Mylist.photo = [[UIImage alloc] initWithData:data]; 
    [sofArray addObject:Mylist]; 



    } 

     if(notExist){ 
      //NSLog(@"cat id does not exist"); 

      const char *sqlInsert = [[NSString stringWithFormat:@"insert into categories (id, cat_name,order_by) values ('%@', '%@', '%@')", [tuser objectForKey:@"id"], [tuser objectForKey:@"cat_name"],[tuser objectForKey:@"order_by"]] cStringUsingEncoding:NSUTF8StringEncoding]; 
      //NSLog(@"stmt is %s", sqlInsert); 

      if(sqlite3_prepare_v2(db, sqlInsert, -1, &addStmt, NULL) != SQLITE_OK) 
       NSAssert1(0, @"Error while creating add statement. '%s'", sqlite3_errmsg(db)); 

      if(SQLITE_DONE != sqlite3_step(addStmt)) 
       NSAssert1(0, @"Error while inserting data. '%s'", sqlite3_errmsg(db)); 

     } 


    } 

    } 

    } 

    } 

    return sofArray; 


} 

    @end 

在viewController.m文件:

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    // Do any additional setup after loading the view. 


    Sofalistsql * mysofs =[[Sofalistsql alloc] init]; 
    self.sofas = [mysofs getMysofas]; 



} 

按鈕即可從服務器顯示圖像:

-(void)click:(id)sender{ 


scrollview=[[UIScrollView alloc]initWithFrame:CGRectMake(0,500,320,200)]; 

     scrollview.showsVerticalScrollIndicator=NO; 
      scrollview.showsHorizontalScrollIndicator=NO; 

     scrollview.scrollEnabled=YES; 

     int Width = 0;  

    // Width = Width + 20+(i*74); 


    for (int i = 0; i<[self.sofas count]; i++) { 
      NSLog(@"index %d",i); 



      // imgView1=[[UIButton alloc]initWithFrame:CGRectMake(20+(i*74), 500, 72, 72)]; 

      imgView1=[[UIButton alloc]initWithFrame:CGRectMake(20+(i*74), 0, 72, 72)]; 

      Width = Width + 20+(i*74); 

      [imgView1 setTag:i+1]; 

      [imgView1 addTarget:self action:@selector(dbsofaClicked:) forControlEvents:UIControlEventTouchUpInside]; 

      [imgView1 setImage:((Mysof *)[self.sofas objectAtIndex:i]).photo forState:UIControlStateNormal]; 

      [scrollview addSubview:imgView1]; 

      // [myScroll addSubview:imgView1]; 



     } 

     [scrollview setContentSize:CGSizeMake(Width,imgView1.frame.size.height+20)]; 

     [self.view addSubview:scrollview]; 



} 

jsonstring.php文件:

<?php 
    require_once('database_connection.php'); 
    $i = 0; 
    $j = 0; 
    $k = 0; 
    $l = 0; 
    mysql_query('SET CHARACTER SET utf8') or die("MYSQL character set error: ".mysql_error()); 
    $result = array(); 
     $sql=mysql_query("SELECT * FROM categories ORDER BY id ASC") or die(mysql_error()); 
     if(mysql_num_rows($sql) > 0) { 
      while($res=mysql_fetch_array($sql, MYSQL_ASSOC)){ 
       $result[0][$i] = $res; 

       $art_sql=mysql_query("SELECT * FROM product WHERE cat_id=" .$res['id']. " ORDER BY id ASC") or die(mysql_error()); 
       if (mysql_num_rows($art_sql) > 0){ 
        while($art_res=mysql_fetch_array($art_sql, MYSQL_ASSOC)){ 
         //$art_res['art_details'] = (utf8_encode(htmlentities($art_res['art_details']))); 
         //$art_res['art_details'] = htmlentities($art_res['art_details']); 
         //echo $art_res['art_details']; 
         $result[1][$k] = $art_res; 
         //print_r($art_res);  
         $k = $k+1; 
        } 
       } 
       $i= $i+1; 
      } 
      $version_sql = mysql_query("SELECT * FROM version_app order by product_id desc limit 1") or die(mysql_error()); 
      $row = mysql_fetch_array($version_sql); 
      $last_version = $row['product_id']; 
      $result['2'][$l] = array('product_id' => $last_version); 
      $l = $l+1; 
     } 


     /*echo "<pre>"; 
      print_r($result); 
     echo "</pre>";exit;*/ 

    $str_enc = json_encode($result); 
    //print_r($str_enc); exit; 
    $str=str_replace('\r','',$str_enc); 
    $str=str_replace('\t','',$str); 
    $str=str_replace('\n','',$str); 
    $str = stripslashes($str); 
    //$str_renc = json_encode(json_decode($str)); 

    echo $str; 

mysql_close(); 
?> 

的NSLog:

userdata is (
     (
       { 
      "cat_name" = Table1; 
      id = 1; 
      "order_by" = 1; 
     }, 
       { 
      "cat_name" = Table2; 
      id = 2; 
      "order_by" = 2; 
     }, 
       { 
      "cat_name" = test; 
      id = 3; 
      "order_by" = 3; 
     } 
    ), 
     (
       { 
      "cat_id" = 1; 
      id = 2; 
      "order_by" = 1; 
      "product_image" = "img.png"; 
     }, 
       { 
      "cat_id" = 1; 
      id = 3; 
      "order_by" = 2; 
      "product_image" = "img1.png"; 
     }, 
       { 
      "cat_id" = 1; 
      id = 4; 
      "order_by" = 3; 
      "product_image" = "img2.png"; 
     }, 
       { 
      "cat_id" = 1; 
      id = 5; 
      "order_by" = 4; 
      "product_image" = "img3.png"; 
     }, 
       { 
      "cat_id" = 1; 
      id = 6; 
      "order_by" = 5; 
      "product_image" = "img4.png"; 
     }, 
       { 
      "cat_id" = 1; 
      id = 7; 
      "order_by" = 6; 
      "product_image" = "img5.png"; 
     }, 

    ) 
) 


array (
) 
2013-08-16 13:19:53.044 App[3395:c07] scroll is <UIScrollView: 0x9de7cb0; frame = (0 300; 320 200); clipsToBounds = YES; gestureRecognizers = <NSArray: 0x9de60e0>; layer = <CALayer: 0x9de4bc0>; contentOffset: {0, 0}> 

我在本地數據庫中存儲了相同的表名。並用覆蓋數據庫。在本地數據庫中,我以BLOB類型存儲圖像。但在我的陣列中,我什麼也沒有顯示。應用正在工作。但圖像不從數據庫中顯示。

+0

你沒有從getMysofas方法傳遞mutableArray的第一件事。第二,爲什麼你要初始化scrollview兩次,一次是viewDidLoad和其他點擊操作。要查看完整的代碼並找出問題的位置非常困難,請調試並顯示實際崩潰的位置。錯誤意味着它是一些內存問題,你正試圖訪問一些已經釋放的對象。 –

+0

使用ARC的Im。所以我評論發佈在JSON文件。它導致錯誤? – user2674668

+0

如何從getMySofas方法傳遞mutuableArray? – user2674668

回答

0

既然您已經包含了您的JSON示例,我可以看到另一個問題:您的JSON是一個由三個數組組成的數組,一組數組,一組產品和一組數組。這是一個有問題的結構(通常一個數組將是同類型的同類項目)。而不是數組的數組,我將它作爲數組的字典。

您的JSON中的這個令人困惑的結構體現在您的Objective-C代碼中。你試圖遍歷userdata數組,但是你不能,因爲這三個項目中的每一個都不相同。

因此,讓我提出兩個可能的修復方案。首先你,如果你堅持你的陣列(我不是瘋了約)的陣列,您無法通過陣列與for循環迭代,但你可以提取三個數組包含像這樣:

NSArray *categories = userdata[0]; 
NSArray *products = userdata[1]; 
NSArray *versions = userdata[2]; 

現在您可以遍歷這三個數組中的每一個。

就我個人而言,我會更進一步,並更改生成JSON的PHP以生成頂級字典,例如,

<?php 
    require_once('database_connection.php'); 
    $i = 0; 
    $j = 0; 
    $k = 0; 
    $l = 0; 
    mysql_query('SET CHARACTER SET utf8') or die("MYSQL character set error: ".mysql_error()); 
    $result = array(); 
     $sql=mysql_query("SELECT * FROM categories ORDER BY id ASC") or die(mysql_error()); 
     if(mysql_num_rows($sql) > 0) { 
      while($res=mysql_fetch_array($sql, MYSQL_ASSOC)){ 
       $result['categories'][$i] = $res; 

       $art_sql=mysql_query("SELECT * FROM product WHERE cat_id=" .$res['id']. " ORDER BY id ASC") or die(mysql_error()); 
       if (mysql_num_rows($art_sql) > 0){ 
        while($art_res=mysql_fetch_array($art_sql, MYSQL_ASSOC)){ 
         $result['products'][$k] = $art_res; 
         $k = $k+1; 
        } 
       } 
       $i= $i+1; 
      } 
      $version_sql = mysql_query("SELECT * FROM version_app order by product_id desc limit 1") or die(mysql_error()); 
      $row = mysql_fetch_array($version_sql); 
      $last_version = $row['product_id']; 
      $result['versions'][$l] = array('product_id' => $last_version); 
      $l = $l+1; 
     } 

    $str_enc = json_encode($result); 

    // note, these str_replace lines are not needed 

    // $str=str_replace('\r','',$str_enc); 
    // $str=str_replace('\t','',$str); 
    // $str=str_replace('\n','',$str); 

    // this stripslashes is a really bad idea, though 

    // $str = stripslashes($str); 

    // you echoed `$str`, but I'll obviously echo @str_enc  
    echo $str_enc; 

    mysql_close(); 
?> 

如果你這樣做,你可以接着用

NSArray *categories = userdata[@"categories"]; 
NSArray *products = userdata[@"products"]; 
NSArray *versions = userdata[@"versions"]; 

檢索您的三個數組這不是一個關鍵任務的變化,但它的三個異質的商品更邏輯表示。但這個想法是一樣的:從你的JSON中提取你的三個數組,現在你可以分別遍歷它們。


一對夫婦的SQLite的相關問題跳出我

  1. 的一個問題是,你有一個行SQL的,上面寫着:

    SELECT id FROM categories where cat_id = '%@' 
    

    但是你繼續嘗試閱讀四欄的數據(即使你只返回一欄)。即使您更改了SQL以實際返回四列數據,您應該確實檢查sqlite3_column_blobsqlite3_column_bytes調用,以確保有一些內容可以填充NSData。另外,構建SQL語句時不使用stringWithFormat,而是使用?佔位符代替printf格式化程序,然後使用sqlite3_bind_xxx函數,通常更安全。

  2. getMysofas重複打開數據庫,但從不關閉它。每撥打一個sqlite3_open電話都有一個sqlite3_close。同樣,您應該爲每個sqlite3_prepare_v2行聲明一個sqlite3_finalize聲明。


除此之外,你必須要麼使用exception breakpoint,以確定飛機墜毀的來源,單步通過這個代碼在調試器中,或把一堆的NSLog聲明在那裏。請參閱Ray Wenderlich的系列My App Crashed, Now What?。但是你確實需要確定導致問題的代碼行。

+0

我在本地數據庫中存儲了相同的表名。並用覆蓋數據庫。在本地數據庫中,我以「BLOB」類型存儲圖像。但在我的陣列中,我什麼也沒有顯示。應用正在工作。但圖像不從數據庫中顯示。 – user2674668

+0

@ user2674668你是否修復了SQL(我的第一點)?您的SELECT語句不檢索圖像數據,因此您對'sqlite3_column_bytes'和'sqlite3_column_blob'的調用將失敗。 – Rob

+0

我真的很困惑。在哪裏更改代碼? – user2674668