IOS 6 by Tutorials---chapter II-"Second play"-"translation"

Source: Internet
Author: User

Fun with instance variablesthe fun of instance variablesTake a look at masterviewcontroller.h:--look at the Masterviewcontroller class .
  @interface  masterviewcontroller:uiviewcontroller <uitableviewdatasource, uitableviewdelegate,detailviewcontrollerdelegate  >   {  Instance Variables for outlets  uitableview  *tableview; Uisegmentedcontrol *segmentedcontrol; ...} @property (nonatomic, strong) Iboutlet UITableView  *tableview; @property ( Nonatomic, Strong) Iboutlet Uisegmentedcontrol  *segmentedcontrol; ....   @end  

Usually when you declare a property, and you want to having it "backed" by an instance variable that stores the actual value for The property. For example, Self.tableview actually reads and writes the value from the TableView instance variable.

Generally you declare an attribute, and you want an instance variable to store the actual value of this property. For example: Self.tableview (property) is actually read and written by TableView this instance variable.

In the @interface above, you can see that the author have declared both the property and its backing instance variable. The instance variable sits inside the {} section and the property on its own line below. (Sometimes you'll see the iboutlet specifier in the instance variable instead of the property. It doesn ' t really matter where it goes.)

In the above declaration, the author declares both the property and the instance variable it supports. The instance variable is declared in the {} section, and the property is outside of it. (It's not important to see iboutlet this keyword decorating instance variables instead of attributes)

When you do this, you ' re essentially writing the same thing twice. Here's the thing:this hasn ' t been necessary for ages! The explicit declaration of the instance variable is only necessary for the IPhone 2.x Simulator because it used an older Version of the OBJECTIVE-C runtime. Quite some time ago now, the Simulator switched to the "modern" runtime, which was also what the actual iPhone uses, and th is workaround became unnecessary.

When you do this, you basically wrote the same thing two times. Here's the thing: it's not necessary. It is necessary to display the declaring instance variable only in the iphone 2.x emulator, as it is using the old version of the OC Runtime. A long time ago, the simulator had switched to the "modern" runtime, which was also used by the iphone, so this solution is not necessary.

When you @synthesize a property, the compiler automatically creates that instance variable for you. That's what @synthesize are for, after all. So there are no need to type the same thing again.

When you synthesize a property, the compiler automatically creates an instance variable associated with it. After all, that's what synthesize to do. So there's no need to do the same thing again.

Note:in Some older versions of Xcode, it used to be so if you allowed the compiler to auto-create instance variables, y Ou couldn ' t see the instance variables in the debugger. Happily, this was no longer the case, and you can now see the instance variables in the debugger as expected. So feel free to auto-generate!

Note: In some older versions of Xcode, if you allow the compiler to create instance variables automatically, you won't see this instance variable in the debugger. Fortunately, this is not the case now, and you can see the instance variable you expect in the debugger. So, feel free to generate instance variables!

So, go ahead and remove these-instance variable declarations from MasterViewController.h, and everything should work a S before.

So, remove these two instance variables from the MasterViewController.h class, and all will work as usual.

Also go ahead and remove all the instance variable declarations from DetailViewController.h. Same story. Each of those instance variables just exists for the sake of the property with the same name. Get rid of ' em.

The instance variables in the DetailViewController.h class are also deleted. Each instance variable exists just to have the same name as the attribute. get rid of them.

The new, simplified @interface section from DetailViewController.h should look like this:

The simplified DetailViewController.h class looks like this:

@interfaceDetailviewcontroller:uiviewcontroller@property (nonatomic, strong) Iboutlet Uinavigationbar*Navigationbar, @property (nonatomic, strong) Iboutlet Uitextfield*TextField, @property (nonatomic, weak)ID<DetailViewControllerDelegate>Delegate; @property (nonatomic, copy) NSString*sectionname; @property (nonatomic, assign) Nsuinteger indexinsection; @property (nonatomic, copy) NSString*name; @property (nonatomic, copy) NSNumber *value;-(Ibaction) Cancel: (ID) sender; -(Ibaction) Done: (ID) sender;@end

Build and run, and everything should work just as before!

Compile and run, all of them are the same as before.

But wait, there's more ...

But, wait, there's more ...

You ' re not doing with the instance variables just yet. Currently the @interface of MasterViewController.h still declares several instance variables:

You are not finished with the instance variable. Currently, several instance variables are still declared in the MasterViewController.h class:

@interface Masterviewcontroller:uiviewcontroller <.. .> {//  Private instance variables  *namesdictionary; Nsmutabledictionary *valuesdictionary; Nsarray *sortedsectionnames; // For the ' sorted by value ' screen  *sortednames; Nsarray *sortedvalues;}

As the comment indicates, these is "private" instance variables. They is used internally by the This view controller is only, and is not supposed to being accessed by any objects outside this CLA SS. (sometimes developers put a @private declaration in there as well.)

Comments indicate that these are private variables. They are only used internally by the controller, and no object outside of this class can invoke these instance variables. (sometimes developers will decorate with @private)

Wouldn ' t it is better if outside objects didn ' t know anything about these instance variables @ all? In and words, why does they need to being exposed in the @interface section in the header file? There is good historical reasons why is necessary, once upon a time–objective-c have been built on top of the C Language, to name One–but as of Xcode 4.2, the compiler No. longer requires this. It is today possible to place instance variable declarations inside your implementation (. m) files instead.

Wouldn't it be better if the external objects weren't aware of these instance variables? In other words, why do they need to leak in @interface in the header file? This is a historical factor, once, OC is built on the C language, after the Xcode4.2, the compiler no longer need this. You can now declare instance variables in the. m file.

Cut the instance variable section out of the header file and paste it directly below the @implementation line in Mastervie WCONTROLLER.M.

to cut the code of an instance variable into a. m fileThe @interface section, MasterViewController.h should now:The MasterViewController.h file looks like this:
@interface Masterviewcontroller:uiviewcontroller < .>*tableview; @property (nonatomic, strong) iboutlet Uisegmentedcontrol *Segmentedcontrol; -(Ibaction) sortchanged: (Uisegmentedcontrol *@end
While the @implementation sections in MASTERVIEWCONTROLLER.M should now look like this:The masterviewcontroller.m file looks like this:
@implementation*namesdictionary; Nsmutabledictionary *valuesdictionary; Nsarray *sortedsectionnames; // For the ' sorted by value ' screen  *sortednames; Nsarray *sortedvalues;}
That's a lot cleaner! Instance variables is typically only necessary inside the. m file, so where they belong.It's a lot of cleaning. Instance variables are only in the. m file that they should be in.

Note:you wonder why some instance variables in this app has properties, and some do not. This is mostly a matter of style–some people like to create properties for everything, and some people don ' t like to CRE Ate properties at all. I only tend to the create properties for things that must is accessible from outside a class, and for Iboutlets.

Note: You may know why some instance variables in this application require attributes, some of which are not required. This is mostly a style-some people like to create all of them as attributes, and some people don't like to create attributes at all. I only create a property or a iboutlets when an object is actually used externally.

To synthesize, or not to synthesize

Countless books and tutorials had probably drilled this rule into you:if you had a @property you need to @synthesize it , at least if you want it to is backed by an instance variable. It is also possible to create your own getter and setters methods or to use @dynamic properties, but most of the time U Se @synthesize.

Most books and tutorials may tell you a rule: if you define a property, if you want support for an instance variable, you need to decorate it with @synthesize. You can also use the @dynamic method to write your own setter and getter methods, but you will actually use @synthesize.

Well, thanks to the automatic synthesize feature in Xcode 4.5, and you don ' t has to bother writing @synthesize statements any more! The compiler would notice your @property statement and automatically synthesize the property and create the backing Instanc e variable for you. Nice, eh?

Of course, since there are new features in Xcode4.5, you can no longer use @synthesize statements. The compiler automatically creates an instance variable corresponding to this property, along with its getter and setter methods.

Try this off by removing the @synthesize statements from APPDELEGATE.M, MASTERVIEWCONTROLLER.M and DETAILVIEWCONTROLLER.M. That's shaves about nine or ten lines from the source code. Now build the app.

Try deleting the @synthesize sentences in appdelegate.m,masterviewcontroller.m and detailviewcontroller.m. That would erase nine lines or 10 lines of code and compile the project.

Whoops, the compiler isn ' t happy! It gives a number of errors in the code for MASTERVIEWCONTROLLER.M, in this method:

Ah yo, the compiler is not smooth! There are a lot of errors in the masterviewcontroller.m file, in this method:

-(void) viewdidload {[Super viewdidload]; if  0//  error! Else  1//  error! [self updatetablecontents];}

The offending lines is the ones that refer to Segmentedcontrol. This used-to-work before you removed @synthesize, so what's the big deal?

The error is segmentedcontrol, before the deletion of @synthesize can be normal operation, so now what is the big deal?

As it turns out, this is an example of programmer sloppiness. If you declare a property for something, then the best practice says all should always refer to it as Self.property and not di Rectly through its backing instance variable. Using Self.property invokes the proper getter and setter methods, but direct access through the backing instance variable Skips those. That may cause issues if your getter or setter does anything special, beyond changing the backing variable.

It turns out that this is an example of a sloppy programmer. If you declare something. The best place to use it is self. Instead of using its instance. With self. The setter and getter methods are called, but the usage instance skips those! If your getter or setter method does something special, it can cause an error.

It's best-to-always write self.property so you've had to worry about any of this. Here, however, the programmer forgot to use "self" and just wrote Segmentedcontrol. The fix is to simply add self. To the references to Segmentedcontrol, as follows:

It is best to use self. , so you can make no mistakes in this respect. Here, the programmer forgets to use self only to write the Segmentedcontrol. The correct method is simply to add self. You can, as follows:

-(void) viewdidload {[Super viewdidload]; if 0 ; Else  1; [ Self updatetablecontents]; }}

This still doesn ' t answer the question of "This" code compiled without problems before you removed @synthesize. That's synthesize statement looked like this:

This is still not an answer to the code before deleting @synthesize, and the synthesize-modified statement looks like this:

@synthesize Segmentedcontrol;

The statement above created a backing instance variable with the same name as the property:in this case, a variable Also Named Segmentedcontrol. So before, weren ' t actually going through the property (Self.segmentedcontrol) –you were accessing the instance Varia ble directly (Segmentedcontrol). This is a easy mistake-make, since the property and instance variable has the same name.

The above statement creates an instance variable with the same name as the property, in which case the variable is also named Segmentedcontrol. So, you didn't actually have to walk the attribute (Self.segmentedcontrol)-it's the instance variable (segmentedcontrol) you accessed directly. It is easy to make such a mistake when the property and the instance variable name are the same.

Seen a variation of the synthesize statement that looks like:

You might see variables and synthesize statements like this:

@synthesize segmentedcontrol = _segmentedcontrol;

The above notation allows-specify a different name for the instance variable. This was a good practice, because it makes it harder to make the above Mistake–you access the property with Self.segmente Dcontrol, and the instance variable with _segmentedcontrol.

The above symbol allows you to specify a different name for the instance variable. This is a good practice because it is not easy to make mistakes like this-you use attributes through Self.segmentedcontrol, using instance variables through _segmentedcontrol.

Also, when you do the the compiler helps-out, just-like-you-saw here. Since your program referenced segmentedcontrol without self, the compiler gave an error because that's neither a valid WA Y to access a property nor the name of a existing variable. It should either is Self.segmentedcontrol or _segmentedcontrol, not just segmentedcontrol.

Similarly, when you do this, the compiler will help you, as you can see. When the compiler references Segmentedcontrol does not use self, the compiler will make an error because this is neither a legitimate way to access the property nor is the instance variable the correct name. To use Self.segmentedcontrol or _segmentedcontrol instead of Segmentedcontrol.

By renaming the instance variable, you prevent the situation where you ' re (mistakenly) using the backing instance variable Directly, when you intended.

By renaming an instance variable, you can prevent an instance variable from being used when you want to use the property.

And that's exactly auto-synthesize Does:it creates a new backing instance variable named after the property, but PR Efixed with a underscore, just as if had typed this:

This is what Auto-synthesize does: it creates a new instance variable that corresponds to the attribute, but the instance variable is underlined in the following format:

@synthesize Segmentedcontrol = _segmentedcontrol;

To verify the-yourself, change the offending lines to:

To verify these, you can change the code to:

_segmentedcontrol.selectedsegmentindex = ...;

Now the code should compile successfully. Even though you never declared this variable anywhere yourself, it still exists because of auto-synthesize. (You probably should-it back to use the property before you continue, though.)

The code can now be compiled successfully. Although you have not declared this instance variable anywhere, it still exists because of the auto-synthesize. (Although you might be able to change it back to using attributes)

Build and run, and everything should work as usual!

Compile and run, all of them are normal.

Tip:your apps don ' t need to being IOS 6-only to take advantage of auto-synthesize. Apps compiled with this feature would still work all the the-the-same-to IOS 4. nice!

Recommendation: Your app does not have to use auto-synthesize under IOS6. This feature can be compiled after the application is iOS4.

Note: This is my experiment translation of some things, but I think the translation is more study, so I decided to translate relatively close to the book it, undeniable, I translated or worse, but slowly!

Come on, dear self!

IOS 6 by Tutorials---chapter II-"Second play"-"translation"

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.