Tải bản đầy đủ - 0 (trang)
Chapter 3. Objective-C for iOS: Email needs variety

Chapter 3. Objective-C for iOS: Email needs variety

Tải bản đầy đủ - 0trang

renee wants more



Renee is catching on....

Mike has been diligently using InstaEmail to communicate his feelings, but his

girlfriend is starting to think something weird is going on. Even for Mike, who

is a guy who likes his routines, his emails are starting to sound suspicious.



InstaEmail is working great and is so easy to use!

But I think Renee is on to me. She said I sound

like I’m in a rut. I need to be able to add some

variation to my emails or this isn’t going to work

much longer.



We need to make some adjustments

to our InstaEmail design.

Take a look at the various UI controls available in

Interface Builder, and think about what would be a

quick and easy way for Mike to add to his emails.



100   Chapter 3

www.it-ebooks.info



objective-c for iOS



Make room for custom input



We’ll put

text fieldthe

in

here.



It’s nothing fancy, but Mike could add a little personal flavor to his

emails with a text field at the start. It means he’ll need to do some

typing, but in the end his emails will be more unique.



Scoot this

stuff down

a little.



Design Magnets



Using what you know from adding the picker and the button, match the

magnet with the method or file that you’ll need to edit to add the text field.



1







2







to the top of

InstaEmailViewController.m.



3







to the dealloc in

InstaEmailViewController.m.



4







to InstaEmailViewController.h.



using Interface Builder.

5







to the property created in step

#1, using Interface Builder.

Create a de

legate and

datasource

for the no

tesField



Declare the UITextField and a

property that’s an IBOutlet

Add

notesField_ to

@synthesize



Add [notes

field_ rele

ase]



Add UITextField

to the view



Add an IBAction for

the UITextField

Link the UITextField

to the IBOutlet



you are here 4   101

www.it-ebooks.info



code magnets solution



Design Magnets Solution



Using what you know from adding the picker and the button, match the

magnet with the method or file that you’ll need to edit to add the text field.







1



Declare the UITextField and a

property that’s an IBOutlet



to InstaEmailViewController.h.



@interface InstaEmailViewController : UIViewController


MFMailComposeViewControllerDelegate> {





UIPickerView *emailPicker_;







NSArray *feelings_;









}



NSArray *activities_;



UITextField *notesField_;



ent

extField. To implasems

IT

U

a

is

ed

ne

e

w

cl

What

need to declare a

the new field, we’ell call notesField_ and add a

member that w d as an IBOutlet.

property marke



@property (nonatomic, retain) IBOutlet UIPickerView *emailPicker;

@property (nonatomic, retain) IBOutlet UITextField *notesField;



Wait a minute. We keep adding

code to this .h file, but I still don’t

know what a .h file really does!

What gives?



InstaEmailViewController.h



A .h file is a header file.

It’s where you declare the interface and methods for a class. All

of the classes we’ve used so far, like UITextField, NSString, and

NSArray, have header files. Take a minute to look through a couple

and start thinking about what is happening in those files.



102   Chapter 3

www.it-ebooks.info



objective-c for iOS



Header files describe the interface to your class

In Objective-C, classes are defined with interfaces in the header file. It’s where you declare whether

your class inherits from anything, as well as your class’s instance variables, properties, and methods.



Interfaces, clasles’ss, method

instance variab d properties

declarations, an

InstaEmailViewController.h



@interface InstaEmailViewController :

UIViewController

@property (nonatomic, retain)

IBOutlet UIPickerView *emailPicker;



- (IBAction) sendButtonTapped: (id) sender;



Here’s our current InstaEmailViewController.h file. Fill in the

blanks and explain what each line does.

#import



#import

@interface InstaEmailViewController : UIViewController


MFMailComposeViewControllerDelegate> {





UIPickerView *emailPicker_;







NSArray* feelings_;









}



NSArray* activities_;



UITextField *notesField_;



@property (nonatomic, retain) IBOutlet UIPickerView*

emailPicker;

@property (nonatomic, retain) IBOutlet UITextField*

notesField;

- (IBAction) sendButtonTapped: (id) sender;



- (IBAction) textFieldDoneEditing:(id) sender;

@end



InstaEmailViewController.h



you are here 4   103

www.it-ebooks.info



sharpen solution



Here’s our current InstaEmailViewController.h file. Fill in the

blanks and explain what each line does.



#import



#import
MFMailComposeViewController.h>



# import incorporates another file

(almost always a header file) into this

file when it’s compiled. It’s used to pull in

classes, constants, etc. from other files.



s #include, except

It’s almost identical toprC’events including the

that it automatically times (so no more #ifndef

same header multiple

MY_HEADER).

Next comes the

class name and,

if

it inherits from

e

u’r

yo

s

te

ica

ind

ce

fa

er

@int

then a colon and something,

ss.

cla

a

re

cla

the super

de

to

ing

go

class’s name.



Objective-C doesn’t support

multiple inheritance...



@interface InstaEmailViewController:

Here, we specify what we inherit from

UIViewController
and what protocols we conform to.

UIPickerViewDelegate,

MFMailComposeViewControllerDelegate>{ Any protocols yo



brackets separatu implement go in angle

are like Java int ed by commas. Protocols

classes in C++, anerfaces or pure virtual

many as you wan d a class can realize as

t.











UIPickerView *emailPicker_;







NSArray* feelings_;









}



NSArray* activities_;



UITextField *notesField_;



This is where we can declare instance

variables of our class.

The syntax for

Basic types like instance variables is just like in

types use an ast int and float are used as-is; C++:

protected accesserisk. By default, all fields arpointer

@private or @pu , but you can change that w e given

ith

blic sections simila

r to C++.



InstaEmailViewController.h



104   Chapter 3

www.it-ebooks.info



objective-c for iOS



Once you’ve closed the field section of your interface, you

can declare properties. @property tells Objective-C that

there will be accessor methods for the given property and

let you use the ‘.’ notation to access them.



d tells the compiler

The @property keywor

will be backed by

this is a property that

er methods.

getter and (maybe) sett

ibutes; we’ll

These are property atetrshortly...

talk more about thes



@property (nonatomic, retain) IBOutlet UIPickerView* emailPicker;



type and

Here are ouarme, just like the

property n e class.

field in th



Builder to recognize

IBOutlet allows Intercafanceattach to controls (like

properties that you InstaEmail).

our notes property in



@property (nonatomic, retain) IBOutlet UITextField* notesField;



an instance

The minus sign meansit’it’s sa class method).

method (a + means tive-C are public.

All methods in Objec



These are the method declarations.



- (IBAction) sendButtonTapped: (id) sender;



- (IBAction) textFieldDoneEditing:(id) sender;



s Interface

IBAction letntify methods

Builder ide e attached to

that can b

events.



@end



IBAction method signatures can have no argument

s, one

argument of type id (which is like an Obje

ct

refe

renc

in Java), or two arguments where one is the id of e

sender and one is a UIEvent*.containing the even the

t that

triggered the call.



@end: ends your class interface declaration.



InstaEmailViewController.h



you are here 4   105

www.it-ebooks.info



magnets solution



Design Magnets Solution (Continued)



Back in that design we

were working on...



Using what you know from adding the picker and the button, match the

magnet with the method or file that you’ll need to edit to add the text field.







1







Declare the UITextField and a

property that’s an IBOutlet



to InstaEmailViewController.h.



NSArray *feelings_;



InstaEmailViewController.h



UITextField *notesField_;







}



@property (nonatomic, retain) IBOutlet UIPickerView *emailPicker;

@property (nonatomic, retain) IBOutlet UITextField *notesField;



2



@

Add notesField to

ze

synthesi







@synthesize emailPicker=emailPicker_;

@synthesize notesField=notesField_;



InstaEmailViewController.m



to the top of

InstaEmailViewController.m.



Here, you synthesize e

accessor methods

for the property. Thth

e

eq

ua

compiler that we’re mapp ls sign tells the

property to the notesFieling our notesField

class. It’s notesField_ th d_ field on the

at actually holds

our values.



OK, so if we declared a property in the

.h file, then adding @synthesize in the .m file

must auto-generate some code, right?



Yes! It generates the getter and setter methods.

Using @property lets the compiler know we have a property,

but that’s not enough. Using the @synthesize keyword in the

implementation files, we can have the compiler auto-generate the

setter and getter method we talked about earlier. The compiler

will generate a getter, and, if it’s a readwrite property, a setter and

implement it based on the @property attributes declared in the .h

file. So what do the different @property attributes do...?



106   Chapter 3

www.it-ebooks.info



objective-c for iOS



Below is a list of the most commonly used property attributes and

definitions. Match each attribute with its definition.



readonly



When you want the property to be modifiable by

people. The compiler will generate a getter and a

setter for you. This is the default.



retain



When you’re dealing with basic types, like ints, floats,

etc. The compiler just creates a setter with a simple

myField = value statement. This is the default, but

not usually what you want.



readwrite



copy



assign



When you’re dealing with object values. The compiler

will retain the value you pass in (we’ll talk more

about retaining in a minute) and release the old

value when a new one comes in.

When you don’t want people modifying the property.

You can still change the field value backing the

property, but the compiler won’t generate a setter.

When you want to hold onto a copy of some value

instead of the value itself; for example, if you want

to hold onto an array and don’t want people to be

able to change its contents after they set it. This

sends a copy message to the value passed in, then

keeps that.



you are here 4   107

www.it-ebooks.info



who does what solution



SOlUTion

Below is a list of the most commonly used property attributes and

definitions. Match each attribute with its definition.



When you want the property to be modifiable by people.

The compiler will generate a getter and a setter for

you. This is the default.



readonly



When you’re dealing with basic types, like ints, floats,

etc. The compiler just creates a setter with a simple

myField = value statement. This is the default, but not

usually what you want.



retain



When you’re dealing with object values. The compiler

will retain the value you pass in (we’ll talk more about

retaining in a minute) and release the old value when a

new one comes in.



readwrite



When you don’t want people modifying the property.

You can still change the instance variable value backing

the property, but the compiler won’t generate a setter.



copy



When you want to hold onto a copy of some value

instead of the value itself; for example, if you want to

hold onto an array and don’t want people to be able to

change its contents after they set it. This sends a copy

message to the value passed in, then keeps that.



assign



Q:



How does the compiler know what field to use to hold the

property value?



A:



By default, the compiler assumes the property name is the

same as the field name, however, it doesn’t have to be. We prefer to

explicitly name them differently so you know when you’re using the

property versus the field. You can specify the field to use to back a

property when you @synthesize it like this:

@synthesize secretString=superSecretField_;.



Q:

A:



What about that nonatomic keyword?



By default, generated accessors are multithread safe and use

mutexes when changing a property value. These are considered

atomic. However, if your class isn’t being used by multiple threads,

that’s a waste. You can tell the compiler to skip the whole mutex thing

by declaring your property as nonatomic. Note that just making your

properties atomic doesn’t mean your whole class is thread safe, so

be careful here.



108   Chapter 3

www.it-ebooks.info



objective-c for iOS



Auto-generated accessors also handle

memory management

Objective-C under iOS doesn’t have a garbage collector and instead uses a mechanism called reference

counting. That involves keeping up with how many references there are to an object, and only freeing it

up when the count drops to zero (it’s no longer being used). You can think of this as object-ownership.

An object can have more than one owner, and as long as it has at least one, it continues to exist. If an

object doesn’t have any owners left (its retain count hits 0), it’s freed and cleaned up.

When using properties, the compiler handles it for us. The properties we’ve declared so far have all

used the retain attribute. When the compiler generates a setter for that property, it will properly handle

memory management for us, like this:



ect type and we want

Retain says we’re using an objsed

to the setter.

to hang onto the object pas



ans no



e

Nonatomic m

locks.



@property (nonatomic, retain) NSString* secretString;



The @pr @synthesize

be in you operty line wou

r @inter

ld

face.



secretString=secretString_;



- (NSString*) secretString {





}



ns

er just ret.ur

il

p

m

o

c

e

h

t

,

g

Here

thing excitin

the value, no



return secretString_;



the property

y

sa

’t

n

id

d

Since we , the compiler will

is readonly setter for us.

generate a



- (void) setSecretString: (NSString*) newValue {





if (newValue != secretString_) {













}



}



[secretString_ release];



secretString_ = [newValue retain];



the

in keyword, sure

a

t

e

r

e

h

t

d

Since we usesetter checks to makedoes

generated lue is different, then retain

the new va n the old value and a of

a release o one—taking ownership

on the new assed in..

the value p



Write the code that Objective-C generates for each property declaration

below. Assume each one is backed by a field named myField_.

1. @property (nonatomic, readonly) NSString* myField

2. @property (nonatomic, retain) NSString* myField

3. @property (nonatomic, assign) NSString* myField



you are here 4   109

www.it-ebooks.info



sharpen solution



Below is the code that the compiler will generate for each

property. Assume each one is backed by a field named myField_.

1. @property (nonatomic, readonly) NSString* myField



- (NSString*) myField {

return myField_;

}

2. @property (nonatomic, retain) NSString* myField



- (NSString*) myField {

return myField_;

}

- (void) setMyField: (NSString*)

newValue {

if (newValue !=myField_) {

[myField_ release];

myField_ = [newValue retain];

}

}



3. @property (nonatomic, assign) NSString* myField



- (NSString*) myField {

return myField_;

}

- (void) setMyField: (NSString*) newValue

{

myField_ = newValue;

}



110   Chapter 3

www.it-ebooks.info



Be careful with this one...N tri

ngs are

reference-counted objects, SS

so

wh

will technically work, having an assile this

property for an NSString is pro ign

bably a

bad idea.

leans and floats,

However, for basic types like boo

Assignment is

you can’t do reference counting.

almost always what you want.



Tài liệu bạn tìm kiếm đã sẵn sàng tải về

Chapter 3. Objective-C for iOS: Email needs variety

Tải bản đầy đủ ngay(0 tr)

×