OBJECTIVE-C 2.0 adds the dot syntax, which is used to simply invoke the accessor of the member variable. Equivalent to Java getter and setter. Because under normal circumstances, writing a accessor for beginners, it is quite easy to make mistakes. For example, there is a member variable of NSString * called name. One of the wrong spellings is:
123 |
-(void)setName:(NSString *)newName { name = newName;}
|
Java classmate certainly can't think of the above code what is wrong? The reason is that objective-c needs to be responsible for the release of memory. Therefore, before changing the reference, the original object release, the new object, also need to retain, the code is changed to this:
1234 |
- () setname: (nsstring * ) newname { [ Name release]; name = [newname retain ; } /span> |
Beginners may think this is right, in fact, it is still wrong, if NewName and name are pointing to the same object, and this object retain count is only 1. After the name release, the object is recycled. So it should be changed to:
123456 |
- (void ) setname: (nsstring *) newname { if ( name != newname) { [name release]; name = [newname retain ; }} /span>
|
This is a correct set function, Java classmates must be frightened, although know so, but this is more troublesome than Java. As a result, OBJECTIVE-C allows programmers to automatically generate these codes using @property + @synthesize keywords (note: Xcode will now automatically add @synthesize keywords by default). So the OBJECTIVE-C programmer was happy. Most of the time there is no need to write getter and setter.
Be careful, however, that the objective-c accessor cannot be used in the INIT and DEALLOC functions! If you write this in Dealloc, there is a problem:
1234 |
- () dealloc { self name = nil; [super dealloc] /span> |
Apple has a dedicated COCOA memory management article in its developer Documentation Library: http://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/ Memorymgmt/memorymgmt.pdf
The 16th page of the article has a section titled: Don ' t use Accessor Methods in Initializer Methods and Dealloc
The article says: The only place you should not use Accessor is the init function and the Delloc function. In the Init function, for a _count
member variable, you should assign a value like this:
1234567 |
- (id) init {< Span class= "line" > self = [super Init; if (self) {< Span class= "line" > _count = [[nsnumber alloc initwithinteger:0];< Span class= "line" > } return self } /span>
|
For an init function with parameters, you should implement the following:
1234567 |
-(id initwithcount: (nsnumber Span class= "o" >*) startingcount { self = [super init ; if (self) {< Span class= "line" > _count = [startingcount copy } return self } /span>
|
For the dealloc, the corresponding wording should be the release:
1234 |
- (void)dealloc { [_count release]; [super dealloc];}
|
But the more depressed is, the article finally did not say why not! Go to StackOverflow on the search, more unreliable saying is so less once function call, faster. The more plausible argument is that, in Init and dealloc, the presence or absence of an object is uncertain, so sending a message to an object may not be successful.
By the way, when we find this article, we have a lot of such error usage in our code. Although the program does not have a serious memory problem, but in order to insure, or intend to change one line, and then I think, this can be done with vim? So I went into vim, started the macro recording with QA, and entered
:%s/self./[/g
Then enter q so that you can use @a to start the macro you just recorded to replace it. Very convenient.
Posted by Tang Qiao 10th, IOS
Do not use accessor in the init and DEALLOC functions