创建 documentsDirectory 的路径会导致 NSInvalidArgumentException 和无法识别的选择器问题
Creating a path to the documentsDirectory results in a NSInvalidArgumentException and unrecognized selector issue
我正在学习 Obj-C,但我终其一生都无法弄清楚为什么会发生此崩溃。这是错误消息:
2018-01-22 16:10:00.009334-0500 ParkSmartObjC[1997:189530] Finished picking media
2018-01-22 16:10:00.163798-0500 ParkSmartObjC[1997:189530] B4A78674-6164-44CE-8EED-153AA8C0BDA2
2018-01-22 16:10:00.164109-0500 ParkSmartObjC[1997:189530] -[__NSSingleObjectArrayI stringByAppendingPathComponent:]: unrecognized selector sent to instance 0x60000020bd00
2018-01-22 16:10:00.167466-0500 ParkSmartObjC[1997:189530] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSSingleObjectArrayI stringByAppendingPathComponent:]: unrecognized selector sent to instance 0x60000020bd00'
*** First throw call stack:
(
0 CoreFoundation 0x0000000109d731cb __exceptionPreprocess + 171
1 libobjc.A.dylib 0x000000010928ff41 objc_exception_throw + 48
2 CoreFoundation 0x0000000109df3914 -[NSObject(NSObject) doesNotRecognizeSelector:] + 132
3 CoreFoundation 0x0000000109cf6178 ___forwarding___ + 1432
4 CoreFoundation 0x0000000109cf5b58 _CF_forwarding_prep_0 + 120
5 ParkSmartObjC 0x0000000107f4d9fa -[PhotoVC imagePickerController:didFinishPickingMediaWithInfo:] + 426
6 UIKit 0x000000010a64507f -[UIImagePickerController _imagePickerDidCompleteWithInfo:] + 127
7 UIKit 0x000000010a644999 __60-[UIImagePickerController didSelectMediaWithInfoDictionary:]_block_invoke + 42
8 libdispatch.dylib 0x000000010c5193f7 _dispatch_call_block_and_release + 12
9 libdispatch.dylib 0x000000010c51a43c _dispatch_client_callout + 8
10 libdispatch.dylib 0x000000010c5256f0 _dispatch_main_queue_callback_4CF + 628
11 CoreFoundation 0x0000000109d35ef9 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 9
12 CoreFoundation 0x0000000109cfa662 __CFRunLoopRun + 2402
13 CoreFoundation 0x0000000109cf9a89 CFRunLoopRunSpecific + 409
14 GraphicsServices 0x000000010eeaf9c6 GSEventRunModal + 62
15 UIKit 0x000000010a1ee23c UIApplicationMain + 159
16 ParkSmartObjC 0x0000000107f4ca9f main + 111
17 libdyld.dylib 0x000000010c596d81 start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
这是崩溃的代码:
- (void) imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info {
if(info[UIImagePickerControllerOriginalImage]) {
UIImage *image = info[UIImagePickerControllerOriginalImage];
NSData *data = UIImageJPEGRepresentation(image, 0.6);
NSString *uuid = [[NSUUID UUID] UUIDString];
NSString *path = [ImageSaveHelper getDocumentsDirectory];
NSLog(@"%@", uuid);
//The UUID prints fine...
NSString *filePath = [[NSString alloc] init];
->>> filePath = [path stringByAppendingPathComponent:uuid]; //SEEMS TO CRASH HERE. WHAT HAVE I DONE WRONG?
[data writeToFile:filePath atomically:YES];
//Save photo to current CarLocation object
RLMRealm *realm = [RLMRealm defaultRealm];
[realm beginWriteTransaction];
self.carLoc.photoUID = uuid;
self.carLoc.isPhotoTaken = YES;
[realm commitWriteTransaction];
self.carImage.image = image;
[picker dismissViewControllerAnimated:YES completion:nil];
}
}
我正在尝试 select 来自 ImagePickerController 的图像,然后使用 UUID 将数据保存到磁盘上的某个位置。当我尝试将 UUID 附加到文件路径时,它似乎崩溃了。我从辅助函数中获取文件路径。我做错了什么?
编辑:这是辅助函数...
+ (NSString*) getDocumentsDirectory {
NSArray *paths = [NSArray arrayWithObjects:NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES), nil];
NSString *filePath = [paths objectAtIndex:0];
return filePath;
}
像这样确保文档路径有效
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
filePath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.jpg",uuid]];
请阅读错误信息:
[__NSSingleObjectArrayI stringByAppendingPathComponent:]: unrecognized selector
明确指出方法getDocumentsDirectory
returns一个Array,而不是单个字符串。所以你必须得到数组的第一个对象:
NSArray *pathArray = [ImageSaveHelper getDocumentsDirectory];
NSString *path = pathArray[0];
NSString *filePath = [path stringByAppendingPathComponent:uuid];
编辑:
你的辅助方法 returns 一个数组,因为你正在用 NSSearchPathForDirectoriesInDomains
的结果初始化一个数组,它已经是一个数组。结果是一个 嵌套 数组
@[@[@"path", @"path", @"path"]];
并且在索引 0 处获取对象仍然是一个数组。
解决办法是把getDocumentsDirectory
改成
+ (NSString*) getDocumentsDirectory {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
return paths[0];
}
那么你可以保留语法
NSString *path = [ImageSaveHelper getDocumentsDirectory];
NSString *filePath = [path stringByAppendingPathComponent:uuid];
PS:我建议学习 Swift 而不是 ObjC。 Swift 编译器不允许你做那些类型不匹配的事情
我正在学习 Obj-C,但我终其一生都无法弄清楚为什么会发生此崩溃。这是错误消息:
2018-01-22 16:10:00.009334-0500 ParkSmartObjC[1997:189530] Finished picking media
2018-01-22 16:10:00.163798-0500 ParkSmartObjC[1997:189530] B4A78674-6164-44CE-8EED-153AA8C0BDA2
2018-01-22 16:10:00.164109-0500 ParkSmartObjC[1997:189530] -[__NSSingleObjectArrayI stringByAppendingPathComponent:]: unrecognized selector sent to instance 0x60000020bd00
2018-01-22 16:10:00.167466-0500 ParkSmartObjC[1997:189530] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSSingleObjectArrayI stringByAppendingPathComponent:]: unrecognized selector sent to instance 0x60000020bd00'
*** First throw call stack:
(
0 CoreFoundation 0x0000000109d731cb __exceptionPreprocess + 171
1 libobjc.A.dylib 0x000000010928ff41 objc_exception_throw + 48
2 CoreFoundation 0x0000000109df3914 -[NSObject(NSObject) doesNotRecognizeSelector:] + 132
3 CoreFoundation 0x0000000109cf6178 ___forwarding___ + 1432
4 CoreFoundation 0x0000000109cf5b58 _CF_forwarding_prep_0 + 120
5 ParkSmartObjC 0x0000000107f4d9fa -[PhotoVC imagePickerController:didFinishPickingMediaWithInfo:] + 426
6 UIKit 0x000000010a64507f -[UIImagePickerController _imagePickerDidCompleteWithInfo:] + 127
7 UIKit 0x000000010a644999 __60-[UIImagePickerController didSelectMediaWithInfoDictionary:]_block_invoke + 42
8 libdispatch.dylib 0x000000010c5193f7 _dispatch_call_block_and_release + 12
9 libdispatch.dylib 0x000000010c51a43c _dispatch_client_callout + 8
10 libdispatch.dylib 0x000000010c5256f0 _dispatch_main_queue_callback_4CF + 628
11 CoreFoundation 0x0000000109d35ef9 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 9
12 CoreFoundation 0x0000000109cfa662 __CFRunLoopRun + 2402
13 CoreFoundation 0x0000000109cf9a89 CFRunLoopRunSpecific + 409
14 GraphicsServices 0x000000010eeaf9c6 GSEventRunModal + 62
15 UIKit 0x000000010a1ee23c UIApplicationMain + 159
16 ParkSmartObjC 0x0000000107f4ca9f main + 111
17 libdyld.dylib 0x000000010c596d81 start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
这是崩溃的代码:
- (void) imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info {
if(info[UIImagePickerControllerOriginalImage]) {
UIImage *image = info[UIImagePickerControllerOriginalImage];
NSData *data = UIImageJPEGRepresentation(image, 0.6);
NSString *uuid = [[NSUUID UUID] UUIDString];
NSString *path = [ImageSaveHelper getDocumentsDirectory];
NSLog(@"%@", uuid);
//The UUID prints fine...
NSString *filePath = [[NSString alloc] init];
->>> filePath = [path stringByAppendingPathComponent:uuid]; //SEEMS TO CRASH HERE. WHAT HAVE I DONE WRONG?
[data writeToFile:filePath atomically:YES];
//Save photo to current CarLocation object
RLMRealm *realm = [RLMRealm defaultRealm];
[realm beginWriteTransaction];
self.carLoc.photoUID = uuid;
self.carLoc.isPhotoTaken = YES;
[realm commitWriteTransaction];
self.carImage.image = image;
[picker dismissViewControllerAnimated:YES completion:nil];
}
}
我正在尝试 select 来自 ImagePickerController 的图像,然后使用 UUID 将数据保存到磁盘上的某个位置。当我尝试将 UUID 附加到文件路径时,它似乎崩溃了。我从辅助函数中获取文件路径。我做错了什么?
编辑:这是辅助函数...
+ (NSString*) getDocumentsDirectory {
NSArray *paths = [NSArray arrayWithObjects:NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES), nil];
NSString *filePath = [paths objectAtIndex:0];
return filePath;
}
像这样确保文档路径有效
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
filePath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.jpg",uuid]];
请阅读错误信息:
[__NSSingleObjectArrayI stringByAppendingPathComponent:]: unrecognized selector
明确指出方法getDocumentsDirectory
returns一个Array,而不是单个字符串。所以你必须得到数组的第一个对象:
NSArray *pathArray = [ImageSaveHelper getDocumentsDirectory];
NSString *path = pathArray[0];
NSString *filePath = [path stringByAppendingPathComponent:uuid];
编辑:
你的辅助方法 returns 一个数组,因为你正在用 NSSearchPathForDirectoriesInDomains
的结果初始化一个数组,它已经是一个数组。结果是一个 嵌套 数组
@[@[@"path", @"path", @"path"]];
并且在索引 0 处获取对象仍然是一个数组。
解决办法是把getDocumentsDirectory
改成
+ (NSString*) getDocumentsDirectory {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
return paths[0];
}
那么你可以保留语法
NSString *path = [ImageSaveHelper getDocumentsDirectory];
NSString *filePath = [path stringByAppendingPathComponent:uuid];
PS:我建议学习 Swift 而不是 ObjC。 Swift 编译器不允许你做那些类型不匹配的事情