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

Posted

技术标签:

【中文标题】从路径获取 UIImage 仅在调试器中单步执行时有效【英文标题】:Getting UIImage from path only works while stepping through in debugger 【发布时间】:2015-01-17 19:50:03 【问题描述】:

在我的应用程序中,我将图像保存到设备“文档”文件中,然后检索它以用作按钮背景。我正在 2 台不同的设备上进行测试,ios 8 上的 iPhone 5 和 iOS 7 上的 iPhone 4。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"

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

更新:这是 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]; 

【问题讨论】:

这段代码(保存或检索图像)是否在后台线程中执行? 不,不是,我进行了一些多线程处理,但我将其全部删除以消除它的任何问题。 你确定你消除了它吗? :) 很抱歉按下,但这听起来确实可能是困难的根源。 你能显示更多代码吗?图片是如何保存的?这段代码在哪里运行? 我刚刚检查了型号,它是 4,它运行的是 7.1.2。我只有几个区域是多线程的,所以很容易取出,但我会仔细检查。虽然我同意你的观点,但它就像一个多线程问题。速度更快的 iPhone 5 没有问题。 【参考方案1】:

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

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

现在,这里的问题是我不希望两者都能工作,永远。这是因为他们期望的东西非常不同。

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

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

如果文件在您的 app bundle 中,则只能通过调用 NSBundle.mainBundle()pathForResource:ofType:(或类似名称)开始导出此路径。

如果文件在别处,则需要使用 NSFileManager 获取包含文件夹并从那里向下钻取。

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

编辑:

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

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

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 目录存在方面做任何事情。

【讨论】:

这里是“路径”的值。 /var/mobile/Applications/7E6B8FFA-B56A-48EF-A788-CDB3842F8BB7/Documents/UserIcons/userIcon0.jpg 好的,但是如果你按照我刚才所说的去做会发生什么:完全删除对imageNamed:的调用? 请按照我的要求做:显示更多代码。例如,我怎么知道pathToSave 是有效的?我怎么知道文件是如何保存的?如果您需要帮助,必须提供更多信息! 仅使用“imageWithContentsOfFile”会保持相同的问题,但也会将其扩展到 iPhone 5。给我一分钟,我会在最初的问题中发布更多代码。 “仅使用“imageWithContentsOfFile”会保持相同的问题,但也会将其扩展到 iPhone 5。”好的!现在我们只解决一个问题。这正是我们想要去的方向。

以上是关于从路径获取 UIImage 仅在调试器中单步执行时有效的主要内容,如果未能解决你的问题,请参考以下文章

在 Chrome 中单步执行 JavaScript 断点时如何查看 DOM?

如何在 Visual Studio 或 CLion 调试器中单步执行 ispc 源文件?

在SIGTRAP之后无法在gdb中单步调试程序

带有 auth0-lock 的 Auth0 仅在使用调试器时进行身份验证,以缓慢单步执行代码

在单元测试中单步调试和调试代码

仅在调试服务工作程序时才会显示推送通知