Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/112.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/5/objective-c/23.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
Ios 第一次方法调用时已填充NSError对象_Ios_Objective C_Nserror_Pointer To Pointer - Fatal编程技术网

Ios 第一次方法调用时已填充NSError对象

Ios 第一次方法调用时已填充NSError对象,ios,objective-c,nserror,pointer-to-pointer,Ios,Objective C,Nserror,Pointer To Pointer,我在阅读G.Lee的《测试驱动的iOS开发》一书时,遇到了这个单元测试,我不理解。首先,如果你需要更多的代码,请马上告诉我 -(void)testDelegateNotifiedOfErrorWhenNewsBuilderFails { MockNewsBuilder *builder = [MockNewsBuilder new]; builder.arrayToReturn = nil; builder.errorToSet = underlyingError;

我在阅读G.Lee的《测试驱动的iOS开发》一书时,遇到了这个单元测试,我不理解。首先,如果你需要更多的代码,请马上告诉我

-(void)testDelegateNotifiedOfErrorWhenNewsBuilderFails
{
    MockNewsBuilder *builder = [MockNewsBuilder new];
    builder.arrayToReturn = nil;
    builder.errorToSet = underlyingError;
    newsManager.newsBuilder = builder;
    [newsManager receivedNewsJSON:@"Fake Json"];
    ...
}

-(void)receivedNewsJSON:(NSString *)objectNotation
{
    NSError *error = nil;
    //  As you see error is nil and I am passing in a nil error.
    NSArray *news = [_newsBuilder newsFromJSON:objectNotation error:&error];
    ...
}

@implementation MockNewsBuilder

-(NSArray *)newsFromJSON:(NSString *)objectNotation error:(NSError **)error
{
    // But once I arrive here, error is no longer nil.
    // (NSError **) error = 0x00007fff5cb887f0 domain: @"Fake Json" - code: 0
    ...
}
错误是如何神奇地自动设置的

更新:

感谢大家的积极讨论和建议。答案解释了调用方是如何得到错误实例的,因为&,我很清楚这一点。我的问题仍然是,为什么被调用方端指向一个已填充的NSError实例,即使它必须是nil。我没有在
newsFromJSON:error:
中设置错误实例,那么它是如何在那里填充的呢

我刚刚更改了
[newsManager receivedNewsJSON:@“Fake Json1”]
newsFromJSON:error:
中的错误实例立即反映出来
(NSError**)error=0x00007fff5b9b27f0域:@“伪Json1”-代码:0
。它非常令人困惑…

这只是指针指向指针的概念。您正在将引用传递给reference error对象&error传递给方法
-(NSArray*)newsFromJSON:(NSString*)objectNotation error:(NSError**)error

这将更新您传递的内存指针处的错误对象

这就是指针对指针的概念

更新:

您的错误对象为零,是的,它是正确的。但是您没有将该错误对象传递给
newsFromJSON
方法,而是传递错误对象的内存地址(
&error
)。这是错误对象的内存地址。
这就是为什么在
newsFromJSON
方法中得到非空值的原因

还有一件事,您可以使用operator(
*
operator)的内容访问
newsFromJSON
方法中的原始对象 比如,
**错误=something

这将更新您在调用方方法中声明的原始对象(
NSError*error
)。
在C、CPP或Objective-C中,&是运算符的地址,*是运算符的内容

&obj->给出obj的内存地址
*obj->给出obj中内存地址的内容。

error
是类型为
NSError*
的变量,即“指向NSError的指针”(在objective-C中,所有对象都作为引用处理,而不是例如C++)

这意味着
error
是一个(本地)变量,它存储实际
NSError
对象的地址,最初为
nil

您调用的方法将创建一个(自动删除的)
NSError
实例。为了获得对该实例的引用,您需要向该方法传递指针的地址,或
&error
,这反过来又是“指向
NSError
的指针”(注意两级间接寻址)

这样做是因为C中函数的参数和Objective-C中方法的参数都是按值传递的:如果您只传递了
error
,那么存储在那里的值(
nil
)将被单独复制,并且无论被调用的方法做了什么,您(调用方)的变量
error
的内容都无法修改。要实现这一点,您需要传递错误的地址,或
&error

这样,被调用的方法可以“更改”
error
(保存在那里的地址)的内容,以便它指向新创建的
NSError
实例

这有意义吗

附录:这是Cocoa中常见的一种模式:被调用的方法可能会失败,而不仅仅是使用返回值来表示成功/失败,并传递额外的“in/out”参数以在失败时检索详细的错误信息。失败时,该方法可以返回
false
NO
0
,等等),但除此之外,还可以在
NSError
实例中提供更详细的错误报告(例如失败原因)


编辑:正如@Droppy所说,考虑到所有涉及的代码都是您自己的(即,不是第一方或第三方框架),除非您明确地将其分配到某个地方,否则不可能将
error
设置为除
nil
之外的任何其他值。也许您应该在调试器中“观察”它,以查看它的设置时间/位置。由于消息似乎被设置为
@“Fake JSON”
,因此您可以做的第一件事是在项目(所有文件)中搜索该字符串

**是指向指针的指针。 这意味着您需要向函数或方法传递指针地址。 Objective-C是C的严格超集。 这意味着在C中,函数和方法只能返回一个值。 有两种方法。 一种是将所有的返回封装在结构、NSDictionary或其他集合中。 这种方式称为输出参数 它正在传入一个指针地址。 C是一种复制语言。但指针是可移植的黑洞,可以让你在C中做一些疯狂的事情。 ObjuleC和C++给你同样的野性。 该错误由苹果的框架代码设置。 Cocoa模式通常是返回BOOL并传入NSError指针地址。 如果布尔为否,则检查N错误。 Apple framework将在您的N错误指针地址框中放置一些礼物

有时它们不使用BOOL,而是返回一个对象或nil


核心基础C框架工作非常相似,大量使用内外参数。 这回答了您的问题。除非这不是第一次调用

newsFromJSON
,或者事先调用了其他东西,否则没有理由填充
n错误。在您显示的代码中,它应该是
nil
@Droppy感谢您引导讨论:我已经更新了问题的更多细节。但这对我来说仍然是个谜