访问property时有无self.的区别

对property的访问,是否加“self.”是有很大区别的,看了以下内容就一目了然了。

内容摘自:http://stackoverflow.com/questions/1295702/setting-an-objective-c-class-property-without-using-a-self-reference

 

Q:

This morning I ran into a crash in an iPhone app I am working on and while I fixed the bug, I'm curious about syntactic reason it was a problem.

Here is my code reduced to simple elements. I am populating items in a TableView using an NSArray for the items. The NSArray is a property:

@interface FooViewController : UITableViewController {
   
NSArray *stuff;
}

@property (nonatomic, retain) NSArray *stuff;

And in my implementation file:

@synthesize stuff;

- (void)viewDidLoad {    
   
NSArray *arr = [[NSArray alloc] initWithObjects:@"", @"Item 1", @"Item 2",  
                                       
@"Lorem", @"Ipsum", nil];
    self
.stuff = arr;

   
[arr release];
}

Now, when I first wrote the method, I accidentally left off the "self." and that caused the bomb. Although while testing, it worked at first blush. I'd tried:

stuff = arr;
NSLog(@"%d", [stuff count]);

But using stuff in other methods bombed. Now that I've fixed the problem, I can use [stuff count] in other places.

So why can I use stuff in some places but in others I must use self.stuff?

 

A1:

This would have also worked properly:

- (void)viewDidLoad {     
    stuff
= [[NSArray alloc] initWithObjects:@"", @"Item 1", @"Item 2",  
                                       
@"Lorem", @"Ipsum", nil];
}

Because the array was retained by alloc. But it's usually better to stick to the dot notation if you have a property and use the autorelease array creation methods, where you get retains "for free" from the property:

- (void)viewDidLoad {     
   
NSArray *arr = [NSArray arrayWithObjects:@"", @"Item 1", @"Item 2",  
                                       
@"Lorem", @"Ipsum", nil];
    self
.stuff = arr;

}

You probably just left it out to keep things simple, but you also need to free this array in dealloc:

- (void)dealloc {     
 
[stuff release]; stuff = nil;
}
A2:

When you use (self) and dot syntax, given the way you defined the property (nonatomic, retain), the NSArray (stuff) is retained.

When you don't, you are still making the assignment, but you aren't retaining the array aside from the implicit retain via alloc+init - and you release it right away.

You can get around assigning via "self.stuff = arr" by doing:

stuff = [arr retain];

But since you defined a property, you obviously WANT to be using dot syntax and having the retain called for you.

A3:

stuff = ... directly references the backing field of the property. It doesn't increase the retain count. As a result, releasing the object somewhere else might take its retain count down to zero and have it deallocated while you're still holding a reference to it. Also, it may cause a memory leak for the previous value of the property.
The reason it looks like working sometimes is that the object is probably not deallocated yet, by someone else.

On the other hand, self.stuff = ... will send a message to the property's set accessor which will take care of retain count.

A4:

The difference between doing:

stuff=arr;

and

self.stuff=arr;

is that in the second case, you're actually calling the automatically-synthesized setStuff: accessor method, which retains the array. In the code you've posted, the array is being created with alloc/initWithObjects, so it already has a retain count of 1.

You just need to change remove the call to [arr release] in your viewDidLoad: method, and all will be well:

- (void)viewDidLoad {     
   
NSArray *arr = [[NSArray alloc] initWithObjects:@"", @"Item 1", @"Item 2",  
                                       
@"Lorem", @"Ipsum", nil];
    stuff
= arr;
}

As you noticed, you can also "fix" this by using self.stuff. I'd recommend against doing that, since it obscures the meaning of the code, and adds additional work that's not needed in most cases. In general, I recommend not using the "self." syntax in your instance methods.

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值