you are here 4 91objective-c for the iPhone We’ll put the text field in here Scoot this stuff down a little Code Magnets Using what you know from adding the picker and the button, match
Trang 1you are here 4 77
iPhone app patterns
@ synthesize goes along wi th the
@property declaration in the h file See Chapter 3 f or more info
The last thing you need to do with tweetPicker is release our reference to it - another memory thing We’ll come back to the memory management in Chapter 3, we promise
InstatwitViewController.m and then add the implementation.
What’s next?
Trang 2connect the outlet to the code
Connect the picker to our outlet
You’re probably expecting this by now! Back into Interface Builder to
make the connection from the UIPickerView to the IBOutlet in our
view controller Right-click on the UIPickerView, grab the circle next
to the “New Referencing Outlet,” and drop it on File’s Owner—our
InstatwitViewController sporting its new tweetPicker outlet
When you click and drag up to
File’s Owner, you will be able to
connect it to the tweetPicker
outlet you just created.
What do you need to do now to get the data out of the picker and into your Twitter message? Think about the “Tweet it!” button press action and how that will need to change
Trang 3you are here 4 79
iPhone app patterns
Use our picker reference to pull
the selected values
Now all that’s left is to use our reference to the picker to get
the actual values Mike selects We need to reimplement the
sendButtonTapped method to pull the values from the
picker Looking at the UIPickerView documentation, the
method we need is selectedRowInComponent: That
method returns a row value, which, just like before, we can
use as an index into our arrays
- (IBAction) sendButtonTapped: (id) sender {
NSString* themessage = [NSString stringWithFormat:@”I’m %@ and feeling %@
about it.”,
[activities objectAtIndex:[tweetPicker selectedRowInComponent:0]], [feelings objectAtIndex:[tweetPicker selectedRowInComponent:1]]]; NSLog(themessage);
NSLog(@”Tweet button tapped!”);
the picker the “%@” in the s tring format get
replaced with the values w e pass in.
To figure out what Mike chose on the picker, we need to ask the picker wha t row
is selected, and get the corr
esponding string from our arrays.
We’re just going to log this message to the console so we can see the string we’re building, and then we’ll send this to Twitter in just a minute Let’s make sure we implemented this correctly first before tweeting to the whole world
ters, integers, etc., but for now we jus t need to insert the t
wo selected strings, so we’ll use %@.
Trang 5you are here 4 81
iPhone app patterns
Ready Bake
Code
//TWITTER BLACK MAGIC
NSMutableURLRequest *theRequest=[NSMutableURLRequest requestWithURL:[NSURL URLWithString:@”http://YOUR_TWITTER_USERNAME:YOUR_TWITTER_PASSWORD@twitter.com/
statuses/update.xml”]
cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];
// END TWITTER BLACK MAGIC
To post to Twitter, we’re going to use their API Rather than
go into a Twitter API tutorial, we’ll give you the code you need to tweet the string Type the code you see below into the InstatwitViewController.m, just below the NSLog with the Twitter message in the sendButtonTapped method
Your username and password need to go in here.
If you don’t have a Twitter account, just go get one!
Just go to twitter.com and register Once you do that, you can enter your username and password, and this will work like a charm
After adding that code, you can just save, build and go It will
now show up on your Twitter feed Go ahead, try it out!
InstatwitViewController.m
Trang 6mike’s feeling great about your app
That is great! Now, Renee is happy and feels included and I don’t actually have to talk out loud about my feelings At all Ever.
Trang 7you are here 4 83
iPhone app patterns
iPhonecross
Flex your vocab skills with this crossword Untitled Puzzle
Header Info 1Header Info 2
3 This typically handles the information itself in the app
6 This is the document Apple uses to evaluate apps for
the App Store
7 You see this listed in the view and it controls the view
9 This component allows for controlled input from several
selections
10 This type of app is typically one screen, and gives you the
basics with minimal interaction
11 These define to which messages the datasource and
4 This app type typically involves hierarchical data
5 This app type is mostly custom controllers and graphics
8 The other name for an *.xib file
Trang 8more app types
We’ve listed a couple of descriptions of a some different apps Using the app description, sketch out a rough view and answer the questions about each one
Generic giant button app
There are several of these currently up for sale
on the app store This app consists of pushing
a big button and getting some noise out of your iPhone
1
What type of app is this?
What are the main concerns in the HIG about this app type?
Book inventory app
This app’s mission is to keep a list of the books
in your library, along with a quick blurb of what it’s about and the author
2
What type of app is this?
What are the main concerns in the HIG about this app type?
Trang 9you are here 4 85
iPhone app patterns
iPhonecross Solution
Flex your vocab skills with this crossword
Untitled Puzzle
Header Info 1Header Info 2
6 This is the document apple uses to evaluate apps for the
App Store [HUMANINTERFACEGUIDE]
7 You see this listed in the view and it controls the view
[FILESOWNER]
9 This component allows for controlled input from several
selections [PICKER]
10 This type of app is typically one screen, and gives you the
basics with minimal interaction [UTILITY]
11 These define to which messages the datasource and
delegate respond [PROTOCOLS]
Trang 10exercise solution
We’ve listed a couple of descriptions of a some different apps
Using the app description, sketch out a rough view and answer the questions about each one
Generic giant button app
There are several of these currently up for sale
on the app store This app consists of pushing
a big button and getting some noise out of your iPhone
1
What type of app is this?
What are the main concerns in the HIG about this app type?
Book inventory app.
This app’s mission is to keep a list of the books
in your library, along with a quick blurb of what it’s about and the author
2
What type of app is this?
What are the main concerns in the HIG about this app type?
Bug button that you push
Just one view
An immersive app
The big thing Apple cares about is that controls “provide an internally consistent experience.” So everything can be custom, it needs to focused and well organized.
A productivity app
The HIG has many more specific rules about this app type, because you’ll be using standard controls EACH control needs to be checked out for proper usage
Another view for details, need to figure out how to get to it
Book list
Some navigation stuff here
Trang 11you are here 4 87
iPhone app patterns
Your iPhone Toolbox
You’ve got Chapter 2 under
your belt and now you’ve
added protocols, delegates, and
datasources to your toolbox For a
complete list of tooltips in the book,
In a picker, each dial is a component
In a picker, each item is a row
Protocols define the messages your class must realize—some of them might be optional
Protocols
Define the messages y our
datasource and delega te must
Works with databases, plis ts, images, and other genera l info that your app will need t o display
Can be the same objec t as a delegate, but has i ts own specific protocols.
Can be in same objec t as the datasource, but has i ts own specific protocols.
Trang 12renee is getting suspicious
This is Renee, Mike’s
girlfriend
It’s so great that Mike and I are communicating now! But I’ve noticed that Mike’s starting to sound like he’s in a rut, saying the same thing over and over again! Is there something we need to talk about?
Sounds like Mike is going
to need some modifications
to InstaTwit to keep his relationship on solid ground
Trang 13this is a new chapter 89
I know these are letters and
all, but I have no idea what
you’re saying
objective-c for the iPhone
3
Twitter needs variety
We did a lot in chapter 2, but what language was that?
Parts of the code you’ve been writing might look familiar, but it’s time you got a sense of
what’s really going on under the hood The iPhone SDK comes with great tools that mean
that you don’t need to write code for everything, but you can’t write entire apps without
learning something about the underlying language, including properties, message passing,
and memory management Unless you work that out, all your apps will be just default
widgets! And you want more than just widgets, right?
Trang 14renee wants more
InstaTwit was 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 to my tweets
or this isn’t going to work much longer
Renee is catching on
Mike has been diligently using InstaTwit 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 tweets are starting to sound suspicious
We need to make some adjustments
to our InstaTwit 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 tweets.
Trang 15you are here 4 91
objective-c for the iPhone
We’ll put the text field in here
Scoot this stuff down a little
Code 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
Add an IBOutlet and @property
declaration for the UITextField
Add [notesfiel d release] Link the UITextField
to the dealloc in InstatwitViewController.m
using Interface Builder
to the property created in step
#1, using Interface Builder
Create a deleg ate and datasource for
the notesField
Add an IBAction for the UITextField
Make room for custom input
It’s nothing fancy, but Mike could add a little personal flavor to his
tweets with a text field at the start It means he’ll need to do some
typing, but in the end his tweets will be more unique
Trang 16IBOutlet UIPickerView *tweetPicker;
IBOutlet UITextField *notesField;
NSArray* activities;
NSArray* feelings;
}
@property (nonatomic, retain) UIPickerView* tweetPicker;
@property (nonatomic, retain) UITextField* notesField;
design 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
Add an IBOutlet and @property declaration for the UITextField
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?
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 you can look through Take a minute to look through a couple and start thinking about what is happening
in those files
Beware of private framework headers
Sometimes you’ll come across a really tempting method that’s not defined in the Apple Documentation Using undocumented APIs will get your app rejected from the iTunes store.
InstatwitViewController.h
Trang 17you are here 4 93
objective-c for the iPhone
- (IBAction) sendButtonTapped: (id) sender;
Here’s our current InstatwitViewController.h file Fill in the
blanks and explain what each line does.
#import <UIKit/UIKit.h>
@interface InstatwitViewController : UIViewController
<UIPickerViewDataSource, UIPickerViewDelegate> {
IBOutlet UIPickerView *tweetPicker;
IBOutlet UITextField *notesField;
NSArray* activities;
NSArray* feelings;
}
@property (nonatomic, retain) UIPickerView* tweetPicker;
@property (nonatomic, retain) UITextField* notesField;
- (IBAction) sendButtonTapped: (id) sender;
- (IBAction) textFieldDoneEditing:(id) sender;
@end
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 if your
class inherits from anything, as well as your class’ fields, properties, and methods
IBOutlet UIPickerView *tweetPicker;
Trang 18IBOutlet UIPickerView *tweetPicker;
IBOutlet UITextField *notesField;
This is where we can declare fields of our class.
Here’s our inheritances and interfaces
It’s almost identical to C’s #include,
except that it automatically prev ents
including the same header multiple
times (so no more #ifndef
MY_HEADER).
@interface indicates you’re
going to declare a class.
Next comes the class name, and
if it inherits from something then a colon and the sup
er class’s name.
Any protocols you implement go in angle brackets separa ted by commas
Protocols are like Java interfaces or pure virtual classes in C++, and a cl ass
can realize as many as you want.
IBOutlet allows Interface Builder t o
recognize fields that you can attach t o
controls (like our notes field in Ins taTwit).
The syntax for fields is just like in C++: Basic types like int and float are used
as is; pointer types use an asterisk By default, all fields are given protec ted access, but you can change tha t with
@private or @public sections simil ar to C++.
Objective-C doesn’t support multiple inheritance
InstatwitViewController.h
Trang 19you are here 4 95
objective-c for the iPhone
@property (nonatomic, retain) UIPickerView* tweetPicker;
@property (nonatomic, retain) UITextField* notesField;
- (IBAction) sendButtonTapped: (id) sender;
- (IBAction) textFieldDoneEditing:(id) sender;
@end
Once you’ve closed the field section of your interface, you can declare properties @property tells Objective-C to autogenerate getter and setter methods for you.
The @property keyword tells the
compiler this is a property that will be
backed by getter and (maybe) setter
These are the method declarations.
@end: ends your class interface declaration.
The minus sign means it’s an instanc e
method (a + means it’s static) All
methods in Objective-C are public.
IBAction lets Inter face
Builder identify methods
that can be attached t o
Trang 20@synthesize tweetPicker, notesField;
magnets solution
Design Magnets Solution (Continued)
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
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 ?
Back in that design we were working on
@property (nonatomic, retain) UIPickerView* tweetPicker;
@property (nonatomic, retain) UITextField* notesField;
Add an IBOutlet and @property declaration for the UITextField
InstatwitViewController.h
InstatwitViewController.m
Trang 21you are here 4 97
objective-c for the iPhone
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
Below is a list of the most commonly used property attributes and
definitions Match each attribute with its definition
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 retains that.
Trang 22who does what solution
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.
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 retains that.
SOlUTion
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 In reality, it doesn’t have to be You can
specify the field to use to back a property when you @synthesize it
like this: @synthesize secretString=_superSecretField;.
Q: What about that nonatomic keyword?
A: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.
Below is a list of the most commonly used property attributes and definitions Match each attribute with its definition
Trang 23you are here 4 99
objective-c for the iPhone
Auto-generated accessors also handle memory
management
Objective-C on the iPhone doesn’t have a garbage collector, so you have to use 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) When you use 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,
Here the compiler jus t returns the value, nothing exci ting.
Since we didn’t say the prop erty
is readonly, the comp iler will generate a setter f or us
Since we used the r etain keyword, the generated setter check s to make sure the new value is dif ferent, then does
a release on the old v alue and a retain
on the new one.
1 @property (nonatomic, readonly) NSString* myField
2 @property (nonatomic, retain) NSString* myField
3 @property (nonatomic, assign) NSString* myField
Trang 24sharpen solution
1 @property (nonatomic, readonly) NSString* myField
2 @property (nonatomic, retain) NSString* myField
3 @property (nonatomic, assign) NSString* myField
However, for basic types like booleans and f loats, you can’t do reference counting Assignment is almost always what you want
Below is the code that the compiler will generate for each property.
Trang 25you are here 4 101
objective-c for the iPhone
I bet that release just lets go of the memory that your properties use up, right?
Objective-C can automatically release references, too.
In addition to retain and release, Objective-C has the concept of an autorelease pool This is basically an array of objects that the runtime will call release on after it’s finished processing the current event To put something in the autorelease pool, you simply send it the autorelease message:
[aString autorelease];
It will still have the same retain count, but after the current event loop finishes, it will be sent a release You won’t want to use this all the time because it’s not nearly as efficient and has some performance overhead It’s not a bad thing to use, but it’s better to explicitly retain and release when you can
You must release objects you create with alloc, new, copy, or mutableCopy
If you create an object with alloc, new, copy, or mutableCopy, it will have a retain count of 1
and you’re responsible for sending a release when you’re done with the object You can also
put the object in the autorelease pool if you want the system to handle sending a release later
1
Consider everything else to have a retain count of 1 and in the autorelease
pool.
If you get an object by any other means (string formatters, array initializers, etc.) you should
treat the object as having a retain count of 1 and put it in the autorelease pool This means
that if you want to hang onto that object outside of the method that got the object, you’ll
need to send it a retain (and a corresponding release later)
2
To keep your memory straight, you need to
remember just two things
Memory management can get pretty hairy in larger apps, so Apple has a couple of
rules established to keep track of who’s in charge of releasing and retaining when
Get it? Memory, remember?
Trang 26memory management up close
Memory Management Up Close
- (void)dealloc {
[tweetPicker release];
[activities release];[feelings release];
[super dealloc];
}
Memory management is definitely important on iPhone, but that doesn’t mean it’s
complicated Once you get the hang of a few key principles, you’ll be able to structure
your app so that it doesn’t leak memory and get you kicked out of the app store
When you create an object, it starts with a count of 1, and different things you do can
raise and lower the count When the count reaches 0, the object is released and the
memory is made available
This is some of the memory management code that YOU have already written!
NSString *aString = [[NSString alloc] init];
1
2
1 2
At first, ther e’s no
memory alloca ted
when you alloc a cl ass, the reference count is set to 1.
Each retain ca ll adds one
to the count
and a release ca ll subtracts one.
If another objec
t (like this array) needs t
o hang onto your objec t,
it will retain it
and release i ts reference when it’s done wi th it.
Once the count gets t o 0, the object’s dea lloc is called and the memory is f reed.
Trang 27you are here 4 103
objective-c for the iPhone
Determine how many references are left at the end of the chunk of code and if
we have to send it a release for each string
NSString *first = [[NSString alloc] init];
NSString *second = [[NSString alloc] init];
[someStringArray addObject:second];
NSString *third = [[NSString alloc] init];
[third autorelease];
NSString *fourth = [NSString
stringWithFormat:@”Do not read %@”, @”Swimming
with your iPhone by TuMuch Monee”];
NSMutableArray *newArray = [[NSMutableArray alloc] init];
NSString *fifth = [[NSString alloc]
initWithFormat:@”Read this instead: %@”, “Financing your
iPhone 4G by Cerius Savar”];
[newArray addObject:fifth];
[newArray release];
NSString *sixth = [NSString stringWithString:@”Toughie”];
NSArray *anotherArray = [NSArray
arrayWithObjects:sixth count:1];
NSDictionary *newDictionary = [NSDictionary
dictionaryWithObjects:sixth forKeys:@”Toughie”
count:1];
NSString *ignoreMe = [sixth retain];
Final Reference Count