Persistence(9)~SQLite3への保存(3)

2011. 03. 05
●サンプルコードの差異

ビューコントローラのソースファイルPersistenceViewController.mの内容ですが、旧版の本書とiPhone OS 3.x版のサンプルコード、そしてiOS 4.x版のサンプルコードでは内容が若干異なります。

そのままの状態で実行した場合、旧版ならびにiPhone OS 3.x版のサンプルコードでは、テキストフィールドに入力したテキストを保存することができません。
(シミュレータのOSがiOS 4.2の場合)

iOS 4.x版のサンプルコードは正常にSQLファイルの読み書きが行われるため、iOS 4.x版で書き込んだデータは、旧版ならびにiPhone OS 3.x版のサンプルコードでも読み込めるのですが、そこからの変更は反映されません。

ただしiPhone OS 3.x版の不具合は、当時マルチタスク非対応であったため、ファイル書き込みのタイミングがapplicationWillTerminate:(アプリケーションの終了直前)となっていることが原因で、タイミングをapplicationWillResignActive:(アプリケーションが非アクティブになる直前)に書き換えると正常に書き込まれます。

修正箇所は、3カ所になります。

PersistenceViewController.h)

・applicationWillTerminate:の宣言の削除

PersistenceViewController.m)

・applicationWillTerminate:の実装部分の一行目をapplicationWillResignActive:に変更
(メソッドの内容は変更無し)

・viewDidLoadの実装部分で、通知センターでのセレクタの呼び出しをapplicationWillTerminate:からapplicationWillResignActive:に変更

しかし旧版のサンプルコードはapplicationWillTerminate:からapplicationWillResignActive:に変更していても正常に書き込まれません。

3つのサンプルコードにおける、SQLite絡みの実装部分(viewDidLoadとapplicationWillResignActive:)の差異は下表の通りです。

 旧版iPhone OS 3.x版iOS 4.x版
viewDidLoadsqlite3_open()sqlite3_open()sqlite3_open()
sqlite3_exec()
(CREATE TABLE)
sqlite3_exec()
(CREATE TABLE)
sqlite3_exec()
(CREATE TABLE)
sqlite3_prepare_v2()
(SELECT)
sqlite3_prepare_v2()
(SELECT)
sqlite3_prepare_v2()
(SELECT)
sqlite3_step()sqlite3_step()sqlite3_step()
sqlite3_finalize()sqlite3_finalize()sqlite3_finalize()
  sqlite3_close()
applicationWillResignActive:  sqlite3_open()
sqlite3_exec()
(INSERT) 
sqlite3_prepare_v2()
(INSERT) 
sqlite3_prepare_v2()
(INSERT)
sqlite3_step()sqlite3_step()
sqlite3_finalize()sqlite3_finalize()
sqlite3_close()sqlite3_close()sqlite3_close()

viewDidLoadでは、SQLデータファイルのテーブルからデータを読み込み、テキストフィールドの値を取得するのですが、iOS 4.x版で最後にsqlite3_close()で一旦閉じている以外は3つとも同じ内容です。

applicationWillResignActive:では、テキストフィールドの値をSQLデータファイルのテーブルに書き込みを行っています。

iOS 4.x版で、viewDidLoadで一旦閉じたデータベースを再度sqlite3_open()で開き直している以外はiPhone OS 3.x版と内容は同じで、sqlite3_prepare_v2()とsqlite3_step()、sqlite3_finalize()を使用しています。

しかし旧版はほぼ同じ内容ながら、ラッパーであるsqlite3_exec()を使用しています。

これはテーブルに書き込む行番号と対応するテキストフィールド文字列をSQLステートメントに組み込む際、旧版ではNSStringオブジェクトとしてSQLステートメントを生成しているのに対し、iPhone OS 3.x版およびiOS 4.x版ではcharオブジェクトとしてSQLステートメントを生成し、行番号とテキストフィールド文字列の組み込みにワイルドカード指定でsqlite3_bind()を利用しているという違いのためです。

sqlite3_bind()を利用するためにはsqlite3_stmtオブジェクトが必要なため、sqlite3_exec()ではなく、sqlite3_prepare_v2()~sqlite3_finalize()を使用しています。

旧版が正常に書き込みできない理由は、sqlite3_bind()を利用せずに、NSStringオブジェクトで行番号とテキストフィールド文字列の組み込みを行ったSQLステートメントの生成をしているためと思われます。

※旧版のサンプルコードには、テキストフィールド文字列の組み込み時にエラーを引き起こす記述があるのですが、その問題を修正しても正常に出力されません。

詳細については以降で触れていきたいと思います。



参考文献

Second Flush/SQLiteのC/C++インターフェイスの導入

はじめてのiPhone3プログラミングはじめてのiPhone3プログラミング
(2009/12/17)
Dave Mark、Jeff LaMarche 他

商品詳細を見る

Beginning Ios 6 Development: Exploring the Ios SdkBeginning Ios 6 Development: Exploring the Ios Sdk
(2012/12/26)
David Mark、Jack Nutting 他

商品詳細を見る






Bose SoundLink around-ear wireless headphones II
0 Comments
Leave a comment
管理者にだけ表示を許可する
Top
0 Trackbacks
Top
Calendar
06 | 2017/07 | 08
Sun Mon Tue Wed Thu Fri Sat
- - - - - - 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 - - - - -
Recent Articles
iTunes


Swift
Categories
Tips
Profile

水月杏香

Author:水月杏香
永遠の初心者プログラマ。

Wish List
WACOM


ARC
Technical Q&A
情報プロパティリストキー
Start Developing iOS Apps Today
BOSE

Bose SoundLink around-ear wireless headphones II
Reference
NSApplicationDelegateプロトコル
NSArrayクラス
NSAutoreleasePoolクラス
NSBundleクラス
NSBundle UIKit追加分
NSCalendarクラス
NSCoderクラス
NSCodingプロトコル
NSCopyingプロトコル
NSDataクラス
NSDateクラス
NSDateFormatterクラス
NSDictionaryクラス
NSEntityDescriptionクラス
NSEnumeratorクラス
NSErrorクラス
NSExceptionクラス
NSFetchRequestクラス
NSFileHandleクラス
NSFileManagerクラス
NSIndexPathクラス
NSIndexPath UIKit追加分
NSKeyedArchiverクラス
NSKeyedUnarchiverクラス
NSKeyValueCodingプロトコル
NSLocaleクラス
NSManagedObjectクラス
NSManagedObjectContextクラス
NSManagedObjectModelクラス
NSMutableArrayクラス
NSMutableCopyingプロトコル
NSMutableDictionaryクラス
NSMutableSetクラス
NSNotificationクラス
NSNotificationCenterクラス
NSNullクラス
NSNumberクラス
NSObjectクラス
NSObject UIKit追加分
NSObjectプロトコル
NSPersistentStoreクラス
NSPersistentStoreCoordinatorクラス
NSPredicateクラス
NSPropertyListSerializationクラス
NSRunLoopクラス
NSSetクラス
NSStringクラス
NSString UIKit追加分
NSTimerクラス
NSTimeZoneクラス
NSURLクラス
NSURLProtectionSpaceクラス
NSURLRequestクラス
NSUserDefaultsクラス
NSValueクラス

UIActionSheetクラス
UIActionSheetDelegateプロトコル
UIActivityIndicatorViewクラス
UIAlertViewクラス
UIAlertViewDelegateプロトコル
UIApplicationクラス
UIApplicationDelegateプロトコル
UIBarButtonItemクラス
UIBarItemクラス
UIButtonクラス
UIColorクラス
UIControlクラス
UIDatePickerクラス
UIDeviceクラス
UIEventクラス
UIFontクラス
UIGestureRecognizerクラス
UIImageクラス
UIImageViewクラス
UIKit Function
UILabelクラス
UINavigationControllerクラス
UINavigationItemクラス
UIPickerViewクラス
UIPickerViewDataSourceプロトコル
UIPickerViewDelegateプロトコル
UIPinchGestureRecognizerクラス
UIResponderクラス
UIScreenクラス
UIScrollViewクラス
UISearchBarクラス
UISearchBarDelegateプロトコル
UISegmentedControlクラス
UISliderクラス
UISwipeGestureRecognizerクラス
UISwitchクラス
UITableViewクラス
UITableViewCellクラス
UITableViewControllerクラス
UITableViewDataSourceプロトコル
UITableViewDelegateプロトコル
UITapGestureRecognizerクラス
UITextFieldクラス
UITextFieldDelegateプロトコル
UITextInputTraitsプロトコル
UITextViewクラス
UITextViewDelegateプロトコル
UIToolbarクラス
UITouchクラス
UIViewクラス
UIViewControllerクラス
UIWebViewクラス
UIWebViewDelegateプロトコル
UIWindowクラス

AVAudioPlayerクラス
AVAudioPlayerDelegateプロトコル

CADisplayLinkクラス
CAEAGLLayerクラス
CALayerクラス

CGAffineTransform
CGBitmapContext
CGColor
CGColorSpace
CGContext
CGGeometry
CGImage
CGPath

EAGLContextクラス
EAGLDrawableプロトコル

Foundation Constants
Foundation Data Types
Foundation Functions

MPMediaItemクラス
MPMediaItemArtworkクラス
MPMediaPlaylistクラス
MPMediaPropertyPredicateクラス
MPMediaQueryクラス
MPMusicPlayerControllerクラス

Randomization Services

System Sound Services
Amazon


OpenGL ES
SQLite
Monthly Archives
Recent Comments
Recent TrackBacks
RSS Link
Visitors
QR Code
QR