从路径获取 UIImage 仅在调试器中单步执行时有效

Getting UIImage from path only works while stepping through in debugger

在我的应用程序中,我将图像保存到设备 "Documents" 文件,然后检索它以用作按钮背景。我正在 2 种不同的设备上进行测试,iPhone 5 在 iOS 8 上,iPhone 4 在 iOS 7 上。iPhone 5 工作正常,但我iPhone 4.

有一个非常奇怪的问题

使用以下代码设置 UIImage "imageToUse" 仅在调试中单步执行时有效。如果我在此代码块前后放置断点,则图像结果为零。如果我改为逐步执行,则图像会正确设置。

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    pathToSave = [paths objectAtIndex:0];
    path = [pathToSave stringByAppendingPathComponent: [NSString stringWithFormat:@"UserIcons/%@", customIcon[i]]]; //customIcon[i] contains "userIcon0.jpg"
    imageToUse = [UIImage imageWithContentsOfFile:path];
    // path contains "/var/mobile/Applications/7E6B8FFA-B56A-48EF-A788-CDB3842F8BB7/Documents/UserIcon‌​s/userIcon0.jpg"

这是一个我以前从未 运行 遇到过的非常奇怪的问题。任何想法可能是什么原因?谢谢大家。

更新:这是我的保存方法和文件夹 check/creation,按照 matt 的要求。

    __block bool exit = NO;
    __block int count = 0;
    while (!exit) {

        // updated with matt's advice
        NSString *docs = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
        Path = [NSString stringWithFormat:@"%@/UserSlides/userSlide%i.jpg", docs, count];

        // check to see if file already exists at the path
        BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:Path];
        // if the path is available, write to disk and then exit
        if (!fileExists) {
            [UIImageJPEGRepresentation(globe.customSlideImage, 1.0) writeToFile:Path atomically:NO];
            BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:Path];
            if (fileExists) {
                UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Save Complete"
                                                                message:nil
                                                               delegate:self
                                                      cancelButtonTitle:@"OK"
                                                      otherButtonTitles:nil];
                [alert show];
                exit = YES;
            }
        }
        else { // otherwise increment the path file name and retry
            count++;
        }
    }

//////////////

     NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
     dataPath = [[paths lastObject] stringByAppendingPathComponent:@"/UserIcons"];
     if (![[NSFileManager defaultManager] fileExistsAtPath:dataPath])
    [[NSFileManager defaultManager] createDirectoryAtPath:dataPath withIntermediateDirectories:NO attributes:nil error:nil]; 

所以我们有这两行:实际上:

imageToUse = [UIImage imageNamed:path]; 
imageToUse = [UIImage imageWithContentsOfFile:path]; 

现在,这里的问题是我不希望 both 工作,ever。这是因为他们对事物的期望截然不同。

  • imageNamed: 想要一个简单的 name,例如 "myFile.jpg"。它会在您的应用程序包 中查找文件 ,而不是其他任何地方。

  • imageWithContentsOfFile: 想要一个真实的路径名。

    • 如果该文件在您的应用程序包中,则只能通过调用 NSBundle.mainBundle()pathForResource:ofType:(或类似)开始派生此路径。

    • 如果文件在其他地方,您需要使用 NSFileManager 获取包含的文件夹并从那里向下钻取。

现在,您在问题中说您正在尝试从 Documents 文件夹中获取文件。那么,imageNamed: 永远不会 从那里获取文件。我的猜测是,也许一个错误会让您以这种方式获取文件,但这不是您应该依赖的东西。因此,您的第一步应该是完全消除该调用并专注于 imageWithContentsOfFile:,它可以满足您的需求。

编辑:

Path = [NSHomeDirectory() stringByAppendingPathComponent:[NSString stringWithFormat:@"Documents/UserSlides/userSlide%i.jpg", count]];

哇哦。这是不是获取文档目录的方式。因此,第一步是正确使用这些目录。获取文档目录:

NSFileManager* fm = [NSFileManager new];
NSError* err = nil;
NSURL* docsurl =
    [fm URLForDirectory:NSDocumentDirectory
               inDomain:NSUserDomainMask appropriateForURL:nil
                 create:YES error:&err];

或者,如果您需要路径字符串:

NSString* docs = [NSSearchPathForDirectoriesInDomains(
    NSDocumentDirectory, NSUserDomainMask, YES) lastObject];

此外,我没有看到您的代码对确保中间 UserSlides 目录存在做任何事情。