2010-02-26 94 views
2
self.flipsidenavigationbar=aNavigationBar; 

为什么这里需要自我? (否则它崩溃)Dot Syntax Issue

[flipsidenavigationbar pushnavigationietm........]; 

为什么这里不需要自己?

请注意,flipsidenavigationbar是一个iVar声明为属性和综合。

谢谢

亚历

+1

btw通常在obj-c对象名称中使用CamelCase。 'flipsideNavigationBar' – kubi 2010-02-26 14:12:04

回答

2

被宣布为 “保留” 属性类型flipsidenavigationbar?我对这是怎么回事的猜测。

为你写它的点语法方法等同于

[self setFlipsidenavigationbar:aNavigationBar]; 

,并调用此方法是可能保留aNavigationBar对象,当你设置它。当你调用

flipsidenavigationbar = aNavigationBar; 

保留它,它有可能被你希望它是,造成你崩溃前发布。

您可以在Obj-C中阅读更多关于dot syntax的信息,它可能会帮助您解决将来出现的类似问题。


另外两张海报说好,但要记住,这两条线是非常重要的:

self.myViewA = myViewB; 
myViewA = myViewB; 

必须是完全无关的潜力。点语法只是方法调用的简写,您可以使该方法调用做任何你想做的事情。就像你在您的评论

我明白,当一个人需要 设置/初始化你需要 放在那里的“自我”的属性提这一点很重要的是,而不是用于处理性能的规则。但是,当你'告诉' 它做某事(在这种情况下,推动 )你不需要自我。

你应该明白到底发生了什么,所以你知道你的点语法使用的效果是什么。我知道,这很让人困惑,但这并不难,每个人都很快就会收拾起来。祝你好运!

+0

aNavigationBar在我将它放入setFlipSideNavigationBar后发布; setFlip ...是一个保留属性。在所有的答案后,我明白,当需要设置/初始化一个属性时,你需要放置'自我'。但是,当你“告诉”它做某件事(在这种情况下推动),你不需要自我。 – 2010-02-28 14:27:16

+0

我编辑了我的答案作为对此评论的回复。 – kubi 2010-03-01 12:58:10

2

由于疯狂是点符号。我实际上建议新的ObjC开发人员完全避免它,因为上述混淆。

flipsidenavigationbar是一个指针。它的只是的指针。如果你说flipsidenavigationbar = aNavigationBar,你用另一个指针替换一个指针。如果您保留了以前的指针,则不会释放它。你不会开始保留aNavigationBar。这是C.这里没有魔法。

self.flipsidenavigationbar不是一个简单的指针(尽管看起来像一个结构)。这是一个方法调用。作为一个右值,它是[self flipsidenavigationbar]。作为一个左值,它是[self setFlipsidenavigationbar:]。这些调用代码。在大多数情况下,setFlipsidenavigationbar:方法包括释放旧值并保留新值。

有几件事情你应该做的,以避免混淆:

  • 总是,总是使用访问器来访问你的高德。切勿直接访问它们。
  • 为了达到这个目的,请不要将您的ivars定义为与您的访问者具有完全相同的名称。所以你会有一个名为_flipSideNavigationBar的伊娃,它映射到flipSideNavigationBar。这个语法是@synthesize foo = _foo
  • 只要您愿意,可以避免使用点符号。我们之前在ObjC编程的时候很少遇到麻烦,因为我们直观地知道它在做什么,而且键入起来更容易一些。但是这对新开发者来说是非常混乱的,我通常建议避免它。学会说[self foo][self setFoo:]。代码会更有意义。
+0

“永远不要将你的ivars定义为与你的访问者具有完全相同的名字” 这是很好的建议,它绝对应该在任何新的可可书籍的第一章。 – kubi 2010-02-26 14:45:10

5

您需要记住的是,点不仅仅是访问iVar的语法,而是调用设置(或获取)ivar的方法的简写。

这意味着self.foo与foo不一样(假设foo是作为属性声明的伊娃)。 self.foo =值;相当于[self setFoo:value];或value = self.foo相当于value = [self foo];当你只写foo时,你直接访问foo而不用任何方法调用。

该区别很重要,因为setter和getter方法通常不只是分配或获取值,而是保留该值。

所以,你的情况,当你写:

self.flipsidenavigationbar=aNavigationBar; 

你实际上是在调用此伊娃setter方法使这条线就相当于:

[self setFlipSideNavigationBar:aNavigationBar]; 

假设属性定义为复制或保留,然后调用setter将保留导航栏。另一方面,如果你写:

self.flipsidenavigationbar = aNavigationBar;

然后你只是设置self.flipsidenavigationbar直接aNavigationBar没有保留的价值,可导致应用程序在访问aNavigationBar后

至于其他问题崩溃:

[flipsidenavigationbar foo]; 

只是一个方法调用,你不必使用点(尽管你可能有时需要),因为你可以直接在实例方法中引用ivars。

(顺便说一句:为什么不使用骆驼案件?这真的很伤眼睛)