Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/google-apps-script/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何解决iphone开发中遇到的EXC_BAD_访问错误_Iphone_Objective C_Cocoa Touch_File Access - Fatal编程技术网

如何解决iphone开发中遇到的EXC_BAD_访问错误

如何解决iphone开发中遇到的EXC_BAD_访问错误,iphone,objective-c,cocoa-touch,file-access,Iphone,Objective C,Cocoa Touch,File Access,我试着做一件简单的事;从互联网上读取图像,将其保存到iphone上应用程序的documents目录中,然后从该文件中读回,以便我以后可以使用它做其他事情。写这个文件很好,但是当我试图读回它时,我在GDB中得到了一个EXC_BAD_访问错误,我不知道如何解决。下面是我的代码的基本外观: -(UIImage *) downloadImageToFile { NSURL * url = [[NSURL alloc] initWithString: self.urlField.text]; NSArr

我试着做一件简单的事;从互联网上读取图像,将其保存到iphone上应用程序的documents目录中,然后从该文件中读回,以便我以后可以使用它做其他事情。写这个文件很好,但是当我试图读回它时,我在GDB中得到了一个EXC_BAD_访问错误,我不知道如何解决。下面是我的代码的基本外观:

-(UIImage *) downloadImageToFile {
NSURL * url = [[NSURL alloc] initWithString: self.urlField.text];

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

NSString *documentsDirectory = [paths objectAtIndex:0];

[paths release]
NSString * path = [documentsDirectory stringByAppendingString:@"/testimg.png"];

NSData * data = [[NSData alloc] initWithContentsOfURL:url];

[data writeToFile:path atomically:YES];

return [[UIImage alloc] initWithContentsOfFile:path];
}
当我尝试从文件初始化UIImage时,返回语句中的代码失败。有什么想法吗


编辑:忽略添加一个最初是代码中出现问题的版本。

这些错误发生在内存管理不当时(例如,对象过早释放或类似情况)

试着做如下的事情

UIImage *myImage = [[UIImage alloc] initWithContentsOfFile:path];
return [myImage autorelease];
我花了很多时间进行实验,同时掌握了释放/自动释放的概念。有时还需要播放retain关键字(虽然在本例中可能不是这样)


另一个选项可能只是路径不存在,或者无法从中读取?

也许,initWithContentsOfFile不接受路径参数?浏览UIImage的不同init方法,我认为有一种不同的方法用于接受路径


也许你还需要做一些更为奇特的事情来创造一条道路?我记得用“捆”做过什么?抱歉说得这么含糊,这是我能马上记住的全部内容。

将斜线从路径上去掉,并确保它在项目中。它是否在该目录中并不重要,但必须将其添加到项目中才能访问它

您的代码显示,您对Objective-C中的内存管理工作方式严重缺乏了解。除了您收到的EXC_BAD_访问错误外,不正确的内存管理还会导致内存泄漏,这在像iPhone这样的小型设备上可能会导致随机崩溃

我建议你把这个通读一遍:


一定要快速回顾一下内存管理规则。不会跳出任何会导致错误的内容,但是您正在泄漏您分配的所有对象。如果您不理解retain/release模式,那么代码中可能还有另一个地方没有正确地保留对象,这就是导致EXC_BAD_访问错误的原因


还要注意的是,NSString有处理文件系统路径的方法,您自己不必担心分隔符。

对我有很大帮助的一件事是在objc_exception_throw上有一个断点。每当我要抛出异常时,我都会点击这个断点,然后可以调试堆栈链。我只是让这个断点在我的iPhone项目中一直处于启用状态

为此,在xcode中,转到左窗格底部附近的“组和文件”并找到“断点”。打开它并单击项目断点,在详细信息窗格(顶部)中,您将看到一个标记为“双击符号”的蓝色字段。双击它并输入“objc_exception_throw”


下次抛出异常时,您将停止,在调试器中,您可以沿着堆栈链返回到导致异常的代码。

不过,一般来说,如果您的代码中有EXC\u BAD\u访问,而您一辈子都无法找出原因,请尝试使用NSZombie(不,我不是开玩笑)

在Xcode中,展开左侧的可执行文件部分。双击与项目同名的列表(应该是唯一的列表)。在弹出的窗口中,转到参数,并在底部单击加号按钮。名称应为NSZombieEnabled,值应设置为YES

这样,当您尝试访问已发布的对象时,您将更好地了解您正在做的事情。一旦你发现了错误,就把这个值设置为NO

希望这对别人有帮助

注意:这特别适用于非ARC内存管理

既然有这么多的观点,并且经过检查的答案恰当地指出“代码显示了对Objective-C中内存管理工作方式的严重缺乏了解”,但还没有人指出具体的错误,我想我应该添加一个涉及这些错误的答案

关于调用方法,我们必须记住的基线级别规则:

  • 如果方法调用包含单词allocnewcopyretain,则我们拥有所创建对象的所有权。如果我们拥有对象的所有权,则我们有责任将其释放

  • 如果方法调用不包含这些词,我们就没有所创建对象的所有权。如果我们没有对象的所有权,释放它不是我们的责任,因此我们永远不应该这样做

让我们看看OP代码中的每一行:

-(UIImage *) downloadImageToFile {
我们开始了一种新的方法。在这样做的过程中,我们开始了一个新的环境,其中每个被创建的对象都生活在其中。请记住这一点。下一行:

    NSURL * url = [[NSURL alloc] initWithString: self.urlField.text];
我们拥有
url
:那里的单词alloc告诉我们我们拥有该对象的所有权,我们需要自己释放它。如果我们不这样做,那么代码将泄漏内存

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
我们不拥有
路径
:不使用这四个神奇的单词,因此我们没有所有权,也决不能自己发布它

    NSString *documentsDirectory = [paths objectAtIndex:0];
我们不拥有
文档目录
:没有神奇的词语=没有所有权

    [paths release]
    NSData * data = [[NSData alloc] initWithContentsOfURL:url];
回顾几行,我们发现我们没有路径,因此当我们试图访问不再存在的内容时,此版本将导致EXC\u BAD\u访问崩溃

    NSString * path = [documentsDirectory stringByAppendingString:@"/testimg.png"];
我们不拥有
路径
:没有神奇的词语=没有所有权

    [paths release]
    NSData * data = [[NSData alloc] initWithContentsOfURL:url];
我们拥有
数据
:这里的单词alloc告诉用户我们拥有对象的所有权,我们需要自己释放它。如果我们不这样做,那么代码将泄漏内存

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
以下两行不会创建或重新发布