开发者

Dot Syntax Issue

开发者 https://www.devze.com 2022-12-21 14:15 出处:网络
self.flipsidenavigationbar=aNavigationBar; why here is needed self? (otherwise it crashes) [flipsidenavigationbar pushnavigationietm........];
self.flipsidenavigationbar=aNavigationBar;  

why here is needed self? (otherwise it crashes)

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

why here self is not needed?

note that flipsidenavigationbar is an iVar de开发者_如何学JAVAclared as property and synthesized.

thank you

Alex


What you need to remember is that the dot is not just a syntax for accessing the iVar but a shorthand for invoking a method for setting (or getting) the ivar.

This means the self.foo is not the same as just foo (assuming foo is an ivar declared as a property). self.foo=value; is equivalent to [self setFoo:value]; or value=self.foo is equivalent to value=[self foo]; When you just write foo then you're accessing foo directly without any method invocation.

The distinction is important because the setter and getter method usually don't just assign or get the value but rather retain the value.

So, in your case when you write:

self.flipsidenavigationbar=aNavigationBar;

You're actually invoking the setter method for this ivar so this line is equivalent to:

[self setFlipSideNavigationBar:aNavigationBar];

Assuming that the property is defined as copy or retained then calling the setter will retain aNavigationBar. On the other hand, if you write:

self.flipsidenavigationbar=aNavigationBar;

Then you're just setting the value of self.flipsidenavigationbar directly and aNavigationBar is not retained which can cause the application to crash when you access aNavigationBar later

Regarding the other question:

[flipsidenavigationbar foo];

Is just a method invocation, you don't have to use the dot (although you may want to sometimes) because you can refer to ivars directly in instance methods.

(BTW: why not use camel case? this really hurts the eyes)


is flipsidenavigationbar declared as a "retain" property type? My guess as to what's happening is this.

The dot-syntax method as you've written it is equivalent to

[self setFlipsidenavigationbar:aNavigationBar];

and this method call is probably retaining the aNavigationBar object when you set it. When you call

flipsidenavigationbar = aNavigationBar;

you are not retaining it, it's likely being released before you want it to be and causing your crash.

You can read more about dot syntax in Obj-C, it'll probably help you with problems like this in the future.


The other two posters said it better, but it's very important to remember that these two lines:

self.myViewA = myViewB;
myViewA = myViewB;

Have the potential to be completely unrelated. Dot syntax is only shorthand for a method call, and you have the potential to make that method call do anything you want. It's important that, instead of having a rule for dealing with properties like you mention in your comment

i understand that when one needs to set/initialize a property you need to put there 'self'. but, when you 'tell' it to do something (in this case to push) you don't need self.

you should understand exactly what is going on, so you know what the effects of your dot-syntax usage are. It's confusing, I know, but it's really not hard and everyone picks it up pretty quickly. Good luck!


Because of the madness that is dot-notation. I actually recommend that new ObjC developers avoid it entirely because of exactly the above confusion.

flipsidenavigationbar is a pointer. It's just a pointer. If you say flipsidenavigationbar = aNavigationBar, you replace one pointer with another pointer. If you were retaining a previous pointer, you don't release it. You don't start retaining aNavigationBar. This is C. There is no magic here.

self.flipsidenavigationbar is not a simple pointer (despite looking exactly like a struct). It is a method call. As an rvalue, it's [self flipsidenavigationbar]. As an lvalue, it's [self setFlipsidenavigationbar:]. These call code. In most cases, the setFlipsidenavigationbar: method includes a release of the old value and a retain of the new value.

There are several things you should do to avoid confusion:

  • Always, always use accessors to access your ivars. Never access them directly.
  • To help achieve this, never define your ivars as having the exact same name as your accessor. So you would have an ivar called _flipSideNavigationBar that maps to flipSideNavigationBar. The syntax for this is @synthesize foo = _foo.
  • Avoid dot-notation for as long as you can stand to do so. Those of us who have been programming in ObjC since before dot-notation seldom have serious trouble with it because we intuitively know what it's doing, and it is a bit easier to type. But it is extremely confusing to new developers, and I typically recommend avoiding it. Learn to say [self foo] and [self setFoo:]. The code will make a lot more sense.
0

精彩评论

暂无评论...
验证码 换一张
取 消