Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/15.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
Objective c self.instance\u var性能命中?_Objective C - Fatal编程技术网

Objective c self.instance\u var性能命中?

Objective c self.instance\u var性能命中?,objective-c,Objective C,让mFoo成为一个实例变量,它是一个已经合成的属性,因此它有默认的setter和getter。我想知道是否有人需要关注使用 self.mFoovs.mFoo如果在逻辑语句中重复访问mFoo 在我看来,如果一个人绝对确定一个方法没有声明局部变量mFoo,并且在一个方法中与mFoo进行了几次逻辑比较,并且该方法被多次调用,那么不通过其访问器方法直接访问mFoo是有意义的 例如: NSMutableArray *mFoo; @property(nonatomic, retain) NSMutableA

让mFoo成为一个实例变量,它是一个已经合成的属性,因此它有默认的setter和getter。我想知道是否有人需要关注使用
self.mFoo
vs.
mFoo
如果在逻辑语句中重复访问mFoo

在我看来,如果一个人绝对确定一个方法没有声明局部变量mFoo,并且在一个方法中与mFoo进行了几次逻辑比较,并且该方法被多次调用,那么不通过其访问器方法直接访问mFoo是有意义的

例如:

NSMutableArray *mFoo;
@property(nonatomic, retain) NSMutableArray *mFoo;
@synthesize mFoo;

-(void)someMethod {
    Bar* b;
    for (int i=0; i<10000; i++) {
        b = [self.mFoo objectAtIndex:i];   // <<<<<<<<<<<<<<<<
        if (b.something == 123) { // do something };
    }
 }
NSMutableArray*mFoo;
@属性(非原子,保留)NSMUTABLEARRY*mFoo;
@合成mFoo;
-(无效)某种方法{
巴*b;

对于(int i=0;i对于每个对
self.mFoo
的访问,如果启用了快速目标C消息分派,则必须调用大约一个C函数(除非编译器优化了该调用)。因此性能影响在大多数情况下都不会明显。在您提到的示例中,您应该使用快速枚举,如

for (Bar *b in self.mFoo) {
    // do whatever you wish to here
}

,这将导致只访问一次
self.mFoo
,并且通常速度更快(例如,如果您的数组实际上是一个列表).

如果您是从另一个类访问属性,则应始终使用访问器方法或点表示法。这只是基本的OO卫生。如果您发现这会导致循环中出现瓶颈或其他问题,您可以考虑一些定制的解决方案

如果您是从类中访问变量,我认为如果您要获取值,直接访问ivar而不是通过属性访问是可以的。但是,如果您要设置值,您应该始终使用属性,这既是为了避免内存泄漏,也是因为setter可能具有应该执行的逻辑

因此:

但是,如果您的ivar甚至没有与之关联的属性,则不必说直接访问它(您没有太多选择…)。就我个人而言,我通常为所有ivar声明属性,除了一些非对象类型的标志或计数器,但许多人没有

在我看来,如果一个人绝对肯定某个方法会 没有局部变量mFoo 声明,一个正在做几个 在一个应用程序中与mFoo进行逻辑比较 方法,该方法称为 很多人都知道,不接触是有道理的 mFoo通过其访问器方法但是 直接的

始终使用访问器。始终。切勿将对象视为结构来直接获取值。这样做会破坏封装等

(请记住,在下面的讨论中,
self.mfoo
[self-mfoo]
完全是同义词)

现在,在这种情况下,您明显的优化是将
self.mfoo
移动到循环之外

然而,真正的问题是,您是否衡量了应用程序的性能,并确定特定的方法调用实际上导致了任何重大开销


如果是这样的话,请进行优化。不过,最有可能的是,在总体方案中没有可测量的开销。

提前编译器无法对其进行优化。由于消息分派和内省在目标C中是如何工作的,因此实际上不可能知道内联一个方法是否安全,除非编译器拥有关于它的完整信息所有链接单元(甚至可能很困难)。由于编译器没有这些信息(Mac OS X支持可加载模块,我们大多数人都没有基础的源代码)。将来,如果您在JIT环境中使用ObjC,可能会执行某种单态分派内联。
(…in…
是一个很好的建议。但是,没有“启用或禁用”在这种情况下是objc消息分派。编译器方面也没有任何优化机会。路易斯:你是对的,我没有想到。bbum:有一个快速目标C消息分派选项,它使这些调用非常快。但是你是对的,消息将始终被发送。快速消息分派选项不适用于所有平台,而且它也适用于所有平台通过在所有进程中将objc_msgSend*函数移动到固定地址中的共享内存位,避免通过DYLD解除引用。@bbum“从不直接获取值…”即使在类内部,您也严格遵守这一点吗?如果类具有与之相关联的属性,您永远不会让类获得自己的ivar值吗?通常,是的。如果存在键值观察,则通过setter/getter将触发观察。@Apple请使用self。在示例代码和Xcode模板中。从Xcode模板创建项目:[window addSubview:[navigationController视图]];[window makeKeyAndVisible];
CGSize sz = [self size]; //ok
CGSize sz = self.size; //ok
CGSize sz = _size; //ok, but be careful

[self setSize:sz]; //ok
self.size = sz, //ok
_size = sz; // DON'T EVER DO THIS!