我开始学习Objective-C并帮助我这样做,我正在使用" Head First iPhone Development"。现在我正在学习SQLite数据库并让它们工作我被告知SQLite文件需要在应用程序的Documents文件夹中,因此我必须移动文件。
我正在使用本书中的示例,但我似乎无法将其付诸实践。每次我编译它我的应用程序崩溃。我有以下警告:"不兼容的Objective-C类型初始化&#struct; NSURL *',期望' struct NSString *'
有没有人有提示如何解决这个问题?
修改
问题似乎是在这两行中,applicationDocumentsDirectory返回一个NSURL,但我告诉它返回一个NSString。我可以告诉它返回一个NSURL,但这给我一个问题,我在下一行使用stringByAppendingPathComponent。有办法解决这个问题吗?
NSString *documentsDirectory = [self applicationDocumentsDirectory];
NSString *writableDBPath = [documentsDirectory stringByAppendingPathComponent:@"iBountyHunter.sqlite"];
这是应用程序崩溃时调试器控制台输出的内容:
2011-02-04 07:33:42.126 iBountyHunter[591:207] -[NSURL stringByAppendingPathComponent:]: unrecognized selector sent to instance 0x6043f80
2011-02-04 07:33:42.128 iBountyHunter[591:207] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSURL stringByAppendingPathComponent:]: unrecognized selector sent to instance 0x6043f80'
*** Call stack at first throw:
(
0 CoreFoundation 0x00f87be9 __exceptionPreprocess + 185
1 libobjc.A.dylib 0x010dc5c2 objc_exception_throw + 47
2 CoreFoundation 0x00f896fb -[NSObject(NSObject) doesNotRecognizeSelector:] + 187
3 CoreFoundation 0x00ef9366 ___forwarding___ + 966
4 CoreFoundation 0x00ef8f22 _CF_forwarding_prep_0 + 50
5 iBountyHunter 0x00001d8e -[iBountyHunterAppDelegate createEditableCopyOfDatabaseIfNeeded] + 107
6 iBountyHunter 0x00001f24 -[iBountyHunterAppDelegate application:didFinishLaunchingWithOptions:] + 37
7 UIKit 0x002ba1fa -[UIApplication _callInitializationDelegatesForURL:payload:suspended:] + 1163
8 UIKit 0x002bc55e -[UIApplication _runWithURL:payload:launchOrientation:statusBarStyle:statusBarHidden:] + 439
9 UIKit 0x002c6db2 -[UIApplication handleEvent:withNewEvent:] + 1533
10 UIKit 0x002bf202 -[UIApplication sendEvent:] + 71
11 UIKit 0x002c4732 _UIApplicationHandleEvent + 7576
12 GraphicsServices 0x018bda36 PurpleEventCallback + 1550
13 CoreFoundation 0x00f69064 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 52
14 CoreFoundation 0x00ec96f7 __CFRunLoopDoSource1 + 215
15 CoreFoundation 0x00ec6983 __CFRunLoopRun + 979
16 CoreFoundation 0x00ec6240 CFRunLoopRunSpecific + 208
17 CoreFoundation 0x00ec6161 CFRunLoopRunInMode + 97
18 UIKit 0x002bbfa8 -[UIApplication _run] + 636
19 UIKit 0x002c842e UIApplicationMain + 1160
20 iBountyHunter 0x00001cf8 main + 102
21 iBountyHunter 0x00001c89 start + 53
)
terminate called after throwing an instance of 'NSException'
答案 0 :(得分:1)
我正在使用书中的例子 但我似乎无法让它发挥作用。 每次我编译它我的应用程序崩溃。 我有以下警告: “不兼容的Objective-C类型 初始化'struct NSURL *', 预期'struct NSString *'
修正警告;您正在将NSURL实例分配给需要NSString实例的内容。
或发布警告&导致它的代码行。
如果您的应用程序崩溃,请发布崩溃。
问题似乎在于这两个问题 用线 applicationDocumentsDirectory 返回NSURL,但我告诉它 返回一个NSString。我可以告诉它 返回NSURL,但这给了我一个 在我使用的下一行的问题 stringByAppendingPathComponent。是 有办法解决这个问题吗?
你不能告诉一个返回NSURL的方法来代替返回NSString。无论是类型转换返回值还是类似以下的赋值都不起作用:
NSString *documentsDirectory = [self applicationDocumentsDirectory];
编译器在该行上发出警告,因为它已被破坏;你不能像NSString那样对待NSURL。
以下内容应该有效:
NSString *documentsDirectory = [[self applicationDocumentsDirectory] path];
答案 1 :(得分:1)
如果应用程序仍然无法在您的模拟器中运行,请记住从模拟器中删除该应用程序,然后再次构建并运行该应用程序。
您可以使用与真实设备相同的方式从模拟器中删除应用程序。
答案 2 :(得分:0)
我有以下警告:“不兼容的Objective-C类型初始化'struct NSURL *',期望'struct NSString *'
问题是您正在调用apple提供的applicationDocumentsDirectory方法,该方法返回NSURL。
答案 3 :(得分:0)
这样就可以了。
// Check the existence of database
NSFileManager *mngr = [[NSFileManager alloc] init];
// If the database doesn't exist in our Document folder we copy it to Documents (this will be executed only the first time we launch the app).
if (![mngr fileExistsAtPath:[NSString stringWithFormat:@"%@/Documents/db.sqlite", NSHomeDirectory()]]){
NSString *filePath = [[NSBundle mainBundle] pathForResource:@"db.sqlite" ofType:nil];
[mngr copyItemAtPath:filePath toPath:[NSString stringWithFormat:@"%@/Documents/db.sqlite", NSHomeDirectory()] error:NULL];
}
[mngr release];
这是applicationDocumentsDirectory方法的另一个版本:
+ (NSString*)applicationDocumentsDirectory {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
return documentsDirectory;
}