關於ListVie來講,數據項的設置有許多種方法,而自界說完成BaseAdapter是最常常用的了,那末這裡我們來說解一下自界說完成BaseAdapter的通俗完成。
MainActivity.java
public class MainActivity extends AppCompatActivity { //數據源 private List<String> data; //ListView控件 private ListView mList; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //獲得控件ID mList = (ListView)findViewById(R.id.mList); data = new ArrayList<>(); //數據賦初值 for(int i = 0; i < 20; i ++){ data.add("數據項"+ i); } //創立適配器 MyAdapter adapter = new MyAdapter(data); //設置適配器 mList.setAdapter(adapter); } }
MyAdapter.java
public class MyAdapter extends BaseAdapter { //數據項 private List<String> data; public MyAdapter(List<String> data) { this.data = data; } @Override /** * 前往數據源的長度,表現ListView的item項顯示若干個 */ public int getCount() { return data == null ? 0 : data.size(); } /** * 前往指定地位的 item 數據源的對象,這個辦法為手動挪用,非設置適配器時刻挪用 * @param position 指定地位 * @return */ @Override public Object getItem(int position) { return data.get(position); } /** * 前往指定地位的 item的標志 id,很少應用到 * @param position 指定地位 * @return */ @Override public long getItemId(int position) { return position; } /** * 工場辦法,設置好模板,前往視圖,每一個視圖是怎樣顯示出來的, 焦點點,怎樣發生一個View, View 外面怎樣 * 放置對應的內容 * @param position 以後加載的地位 * @param convertView 復用的view * @param parent listview * @return */ @Override public View getView(int position, View convertView, ViewGroup parent) { //獲得結構 View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item,null); //獲得結構中的TextView控件1 TextView tv1 = (TextView) view.findViewById(R.id.mTv1); //設置控件1的數據 tv1.setText(data.get(position)); //獲得結構中的TextView控件2 TextView tv2 = (TextView) view.findViewById(R.id.mTv2); //設置控件2數據 tv2.setText(data.get(position)); return view; } }
以上是通俗的應用,然則如許的效力會異常低,由於每次加載一個item都邑挪用getView辦法,而每次都邑去解析一個view結構,如許一向解析會對內存的消費特殊年夜,所以效力會年夜年夜下降,那末我們在此基本上先略微優化下,讓view解析次數變少一點,最根本的操作就是采取convertView復用控件來停止操作。
這裡只須要修正getView辦法中的處置:
@Override public View getView(int position, View convertView, ViewGroup parent) { Log.i("TAG", "getView: " + position); if (convertView == null) { convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item, null); } TextView tv1 = (TextView) convertView.findViewById(R.id.mTv1); tv1.setText(data.get(position)); TextView tv2 = (TextView) convertView.findViewById(R.id.mTv2); tv2.setText(data.get(position)); return convertView; } }
以上的處置方法比擬下面的處置方法絕對於下面的解析要少許多次,由於第一種完成方法是任何一個須要顯示的控件都須要去解析一次結構,而這裡我們應用了體系給的converView復用控件,他的根本道理是,體系會主動創立好界面顯示n個item的數據項(好比一個界面可見的item為5個,默許創立好了5個view結構對象),保留到converView中(這裡可以把他當做一個輪回數組吧,他的總容量相當因而n + 1),當顯示第n + 1個的時刻,他會解析一次,以後的顯示的view結構會復用本身的converView中曾經存在的結構項,而不再去從新解析。簡略的畫個圖吧:
如上圖所示,相當於只解析了6次,其他的view都是復用的,所以絕對於下面的完成,如許的效力會絕對高一點,不外,固然解析的次數是少了,然則每一個控件須要findViewById照樣會反復挪用,並且其實每一個分歧對象view中的控件id對象確定是雷同的,所以,反復的去挪用又會顯得效力不高,那末若何處理不反復findViewById呢,那就要應用到我們的優化結構了,關於優化,將鄙人一篇博客中引見。
以上就是本文的全體內容,願望對年夜家的進修有所贊助,也願望年夜家多多支撐本站。
��外面稀有據。 // 不然我們的成果集就是空的。 while (SQLite3_step(rc)==SQLite_ROW) { // SQLite3_column系列函數。普通有兩個輸出參數。第一個是成果集指針,第二是數據地點列的序號。 // 好比我們如今用的sqlite3_column_int和sqlite3_column_text。 printf("id:%d | username:%s | password:%s \n",sqlite3_column_int(rc, 0),sqlite3_column_text(rc, 1),sqlite3_column_text(rc, 2)); } // 查完後必定要釋放成果集。 sqlite3_finalize(rc); [self close];數據庫加密
收費版的SQLite有一個致命缺陷:不支撐加密。這就招致存儲在SQLite中的數據可以被任何人用任何文本編纂器檢查到。
對數據庫加密的思緒有兩種:
1. 將內容加密後再寫入數據庫
這類方法應用簡略,在入庫/出庫只須要將字段做對應的加解密操作便可,必定水平上處理了將數據光禿禿裸露的成績。
不外這類方法其實不是完全的加密,由於數據庫的表構造等信息照樣能被檢查到。別的寫入數據庫的內容加密後,搜刮也是個成績。
2. 對數據庫文件加密
將全部數據庫全部文件加密,這類方法根本上能處理數據庫的信息平安成績。今朝已有的SQLite加密根本都是經由過程這類方法完成的。這裡就引見一個開源的加密對象SQLCipher,裝置辦法可以參照官網文檔,https://www.zetetic.net/sqlcipher/IOS-tutorial/,SQLCipher應用256-bit AES加密,因為其基於收費版的SQLite,重要的加密接口和SQLite是雷同的,但也增長了一些本身的接口。
其實SQLite的兩個加密函數應用起來異常的簡略,上面分情形解釋:
1 給一個未加密的數據庫添加暗碼:假如想要添加暗碼,則可以在翻開數據庫文件以後,封閉數據庫文件之前的任什麼時候刻挪用sqlite3_key函數便可,該函數有三個參數,個中第一個參數為數據庫對象,第二個參數是要設定的暗碼,第三個是暗碼的長度。例如:sqlite3_key(db,”1q2w3e4r”,8); //給數據庫設定暗碼1q2w3e4r
2 讀取一個加密數據庫中的數據:完成這個義務仍然非常簡略,你只須要在翻開數據庫以後,再次挪用一下sqlite3_key函數便可,例如,數據庫暗碼是123456時,你只須要在代碼中參加sqlite3_key(db,”123456″,6);
3更改數據庫暗碼:起首你須要應用以後的暗碼准確的翻開數據庫,以後你可以挪用sqlite3_rekey(db,”112233″,6) 來更改數據庫暗碼。
4 刪除暗碼:也就是把數據庫恢復到明文狀況。這時候你依然只須要挪用sqlite3_rekey函數,而且把該函數的第二個參數置為NULL或許””,或許把第三個參數設為0。
事務操作
那末成績又來了,假如IOS的sqlite同時拔出或許查詢10000條數據,你該怎樣辦?
這裡有三步要做,第一,削減開關數據庫操作,拔出10000條數據,不克不及開關10000次數據庫,只能停止一次開關;
第二,就是不克不及放在主線程;
第三,最主要的一點就是參加事務操作。
事務(Transaction)是拜訪並能夠更新數據庫中各類數據項的一個法式履行單位(unit)。在sqlite拔出數據的時刻默許一條語句就是一個事務,有若干條數據就有若干次磁盤操作。所以10000次磁盤操作能夠幾分鐘都做不完,這個時刻須要把10000條語句都封裝成一個事務。
上面就是開端事務和提交事務的代碼了
-(int)beginService{ char *errmsg; int rc = sqlite3_exec(database, "BEGIN transaction", NULL, NULL, &errmsg); return rc; } -(int)commitService{ char *errmsg; int rc = sqlite3_exec(database, "COMMIT transaction", NULL, NULL, &errmsg); return rc;}
接上去就把三個操作歸並
-(int)addModelsTest:(NSArray *)models error:(NSError **) error{ char *errmsg; __block NSMutableArray *sqls=[NSMutableArray array]; __block NoticeModel *aModel=[[NoticeModel alloc] init]; dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ for (int i=0; i<100000; i++) { aModel=[models objectAtIndex:0]; NSString *sql=[NSString stringWithFormat:@"insert into notices values('%lf','%d','%@','%@','%@','%d','%d','%d','%d','%@')",aModel.myID,aModel.news_id,aModel.news_title,aModel.content,aModel.pic,aModel.sort,aModel.record_status,aModel.counter,aModel.suid,aModel.publish_time]; [sqls addObject:sql]; } int r1=[self open]; [self beginService]; int rc; int i; for (i=0; i<100000; i++) { rc=sqlite3_exec(database, [[sqls objectAtIndex:i] UTF8String], NULL, NULL, &errmsg); } [self commitService]; [self close]; if (i ==100000) { dispatch_async(dispatch_get_main_queue(), ^{ NSLog(@"call back, the data is: %@", i); }); } else { NSLog(@"error when download:%@", error); } }); return 0; }
有關IOS中SQLite應用教程小編就給年夜家引見這麼多,願望對年夜家有所贊助!
【iOS中SQLite應用教程】的相關資料介紹到這裡,希望對您有所幫助! 提示:不會對讀者因本文所帶來的任何損失負責。如果您支持就請把本站添加至收藏夾哦!