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
Iphone 为什么被调用方返回自动释放对象而不是返回保留对象并让调用方释放对象?_Iphone_Objective C_Ios_Cocoa - Fatal编程技术网

Iphone 为什么被调用方返回自动释放对象而不是返回保留对象并让调用方释放对象?

Iphone 为什么被调用方返回自动释放对象而不是返回保留对象并让调用方释放对象?,iphone,objective-c,ios,cocoa,Iphone,Objective C,Ios,Cocoa,例如: 我们总是这样写1: -(NSObject*)giveMeAnObject { return [[[NSObject alloc] init] autorelease]; } -(void)useObject { NSObject *object = [self giveMeAnObject]; //use that object } 但是我们为什么不这样写呢2: -(NSObject*)giveMeAnObject { return [[NSObjec

例如: 我们总是这样写1:

-(NSObject*)giveMeAnObject
{
    return [[[NSObject alloc] init] autorelease];
}

-(void)useObject
{
    NSObject *object = [self giveMeAnObject];
    //use that object
}
但是我们为什么不这样写呢2:

-(NSObject*)giveMeAnObject
{
    return [[NSObject alloc] init];
}

-(void)useObject
{
    NSObject *object = [self giveMeAnObject];
    //use that object
    [object release];
}
Cocoa SDK的功能类似于方式1,我认为这就是为什么我们都使用方式1,它已经成为一种编码惯例。 但我只是认为,如果公约是方式2,我们可以获得很少的性能改进


那么,除了编码约定之外,我们使用方式1而不是方式2还有其他原因吗?

返回自动释放的对象是一种抽象形式——对开发人员来说是一种方便,因此他/她不必考虑返回对象的引用计数——从而减少特定类别中的错误(尽管您也可以说自动释放池引入了新的bug类别或复杂性)它确实可以简化客户端代码,虽然是的,可以有性能惩罚。当没有引用操作时,它也可以被用作抽象优化。考虑对象保存返回的实例,而不需要保留或复制。尽管链接语句可以被过度使用,但这种做法是lso便于链接语句

此外,用于确定引用计数错误的静态分析器对于某些库和程序来说相对较新。Autorelease池比ARC和静态分析objc对象的引用计数早很多年——使用这些工具,确保引用计数正确现在要简单得多。它们能够检测到许多ugs

当然,使用ARC,如果您喜欢返回自动释放对象的简单性,那么会有很多变化——使用ARC,您可以返回更少的自动释放对象,而不会引入抽象的错误自动释放池

使用统一的所有权语义还可以简化程序。如果抽象选择器或选择器集合总是使用相同的语义返回,那么它确实可以简化一些通用形式。例如,如果传递给
performSelector:
的一组选择器在返回时具有不同的所有权语义,那么它将为因此,返回时的统一所有权确实可以简化一些更“通用”的实现

性能:引用计数操作(保留/释放)这可能相当重要,尤其是当您习惯于在较低级别工作时。但是,当前的自动释放池实现非常快。它们最近已经更新,并且比以前更快。编译器和运行时使用几种特殊的快捷方式来保持这些低成本。保持自动释放池的运行也是一个好主意ol的大小减小了——特别是在移动设备上。创建自动释放池的速度非常快。在实践中,您可能会看到自动释放操作本身从零增加到几个百分点(即,它比
objc\u msgSend
+变体消耗的时间少得多).有些测试甚至运行得稍快一些。这不是一个很多人都能从中获益的优化。在典型情况下,它不符合低挂果实的条件,而且实际上在实际程序中测量此类更改的效果和位置相对较难——基于我在bbum提到以下更改后所做的一些测试。因此,测试范围有限,但在MRC和ARC中似乎更好/更快


因此,这在很大程度上取决于您在执行自己的引用计数操作时要承担的责任级别。对于大多数人来说,这不应该真正改变他们的写入方式。我认为,内存问题的本地化、更确定的对象破坏和更可预测的堆大小是导致一个错误的主要原因如果您在现代系统上运行,则可能会返回一个“拥有的”(+1)引用计数。即使如此,运行时和编译器也会在许多情况下为您减少此计数(请参阅bbum的答案+1)。尽管自动释放池的速度差不多一样快,但我并不打算比现在更多地使用它们——因此,仍然有合理的理由尽量减少使用它们,但原因正在减少。

返回自动释放对象是一种抽象形式——对开发人员来说是一种方便,因此他/她不必思考关于返回对象的引用计数——因此在特定类别中导致更少的bug(尽管您也可以说自动释放池引入了新的bug类别或复杂性)它确实可以简化客户端代码,虽然是的,可以有性能惩罚。当没有引用操作时,它也可以被用作抽象优化。考虑对象保存返回的实例,而不需要保留或复制。尽管链接语句可以被过度使用,但这种做法是lso便于链接语句

此外,用于确定引用计数错误的静态分析器对于某些库和程序来说相对较新。Autorelease池比ARC和静态分析objc对象的引用计数早很多年——使用这些工具,确保引用计数正确现在要简单得多。它们能够检测到许多ugs

当然,使用ARC,如果您喜欢返回自动释放对象的简单性,那么会有很多变化——使用ARC,您可以返回更少的自动释放对象,而不会引入抽象的错误自动释放池

使用统一的所有权语义还可以简化程序。如果抽象选择器或选择器集合总是使用相同的语义返回,那么它确实可以简化一些通用形式。例如,如果传递给
performSelector:
的一组选择器在返回时具有不同的所有权语义,那么它将为因此,返回时的统一所有权确实可以简化一些更“通用”的实现

表演家