星火杯项目笔记【13-10-12】

来源:互联网 发布:淘宝 递四方 编辑:程序博客网 时间:2024/04/30 02:21

总结一下今天遇到的几个问题:


一、关于NSBundle

NSBundle里的文件都是readonly,不可修改,我在NSBundle里读取一个sqlite文件,然后用sql语句更新数据库,发现数据并没有保存 

NSString *dataPath = [[NSbundle mainBundle] pathForResources:@"data" ofType:@"sqlite"];

以这为路径打开的数据库是不可更改的。


解决方法:把sqlite文件先拷贝到用户目录下

苹果官方建议的目录是Document目录,因此依照以下代码进行拷贝

NSString *beginPath = [[NSBundle mainBundle] pathForResource:@"data2" ofType:@"sqlite"];NSString *targetPath = [NSSearchPathForDictionariesInDomains(NSDocumentDicrectory, NSUserDomainMask, YES) objectAtIndex:0];//注意以下这个语句NSSearchPathForDictionariesInDomains(NSDocumentDicrectory, NSUserDomainMask, YES)的第一个参数,如果第一个参数一不小心写成NSDocumentationDicrectory,也会发生一系列的错误,比如无法创建文件等。 暂时不知道为什么NSString *targetFile = [targetPath stringByAppendingPathComponent:@"data2.sqlite"];NSFileManager *fm = [NSFileManager defaultManager];if (![fm fileExistsAtPath:targetFile]){NSError *error;[fm copyItemAtPath:beginPath toPath:targetFile error:&error]; //注意第二个参数一定要是以文件名结尾的路径,而不能是目录路径,否则会出错“this operation cann't be completed” }sqlite3_open([targetFile UTF8String], &database);

二、内存管理问题

之前程序的占用内存随着程序的使用时间而增加,肯定是哪里有内存泄漏了,检查发现sqlite3_step执行后忘了sqlite3_finalize,这会导致严重的内存泄漏,切记

三、模拟器运行正常,真机却不行

我有一个这样的类:HLOptionContent,用于存储一个选项的内容

@interface HLOptionContent : NSObject@property (weak nonatomic) NSString *kara;@property (weak, nonatomic) NSString *japaneseWord;- (id)initWithKara:(NSString *)kara japaneseWord:(NSString *)japaneseWord;@end


我在初始化选项的时候这样写到

        

//查询其他3个日文(只检索japansesWord)        self.arrayOfJapaneseWord = [[NSMutableArray alloc] init];        const char *query = "select japanese_word,kana from word_tbl where word_id <> ? order by random()  limit 3";        sqlite3_stmt *queryStmt;        int result = sqlite3_prepare_v2(wordDatabase, query, -1, &queryStmt, nil);        if (result == SQLITE_OK) {            sqlite3_bind_int(queryStmt, 1, self.wordID);            while (sqlite3_step(queryStmt) == SQLITE_ROW) {                NSString *aJapaneseWord = [NSString stringWithCString:(const char *)sqlite3_column_text(queryStmt, 0) encoding:NSUTF8StringEncoding];                NSString *aKara = [NSString stringWithUTF8String:(const char *)sqlite3_column_text(queryStmt, 1)];                HLOptionContent *aOption = [[HLOptionContent alloc] initWithKara:aKara japaneseWord:aJapaneseWord];                [self.arrayOfJapaneseWord addObject:aOption]; //MARK            }        }        sqlite3_finalize(queryStmt);        HLOptionContent *aOption = [[HLOptionContent alloc] initWithKara:self.pronunceKara japaneseWord:self.japaneseWord];        [self.arrayOfJapaneseWord addObject:aOption];//把当前待背单词的日文也加进来


这段代码在模拟器上完全正常,4个选项可以在View中正常显示,而在真机中却不行。在上面的MARK处插了个断点开始调试,在真机中发现当aOption被加入self.arrayOfjapaneseWord后,它的kara和japaneseWord都是nil。想想也应该是这样,因为这两个属性都是weak。然后我把HLOptionContent的两个属性都改成strong后,运行正常。但奇怪的是,属性是weak的时候,在模拟器中插断点调试发现这两个属性的值并不为空!!!