RIP Steve Jobs.


He truly was a great man. Namaste.

WWDC 2011—Initial Impressions


Today Apple began the annual WWDC week with a keynote that introduced OS X Lion, iOS 5, and iCloud. If you haven’t done so yet, check out the keynote stream. Rather than just re-iterate the new features, I’d like to share some of my thoughts.

Lion

At first, I have to say that as far as features go, it was a bit underwhelming. I do have to say , I’ve been using pre-release seeds of Lion. Because of the NDA, I can’t talk too much more about the exact features…

Having seen and used these features, I realized that from a new user’s perspective the features are actually really compelling. Why did I find them underwhelming? It’s because the features have integrated themselves so smoothly and seamlessly into my daily experience that they’re really not obtrusive. Some commentary:

  • Gestures: I love them. Takes a bit of getting used to at first, but really integrate into my user experience. I love being able to touch everything and directly interact with it. My only complaint is that there is (at the moment, at least) no built-in ability to define custom gestures.
  • Full Screen: Very useful on laptops, not so much on desktops. Could be useful in some cases, but I’m not sure I like it at all. Its usefulness is doubtful, in my opinion.
  • LaunchPad & MAS: The App Store is actually really nice. Convenient, easy, accessible—everything is as advertised. As far as LaunchPad goes, I find it easy enough to use, and with the gesture to invoke from my Magic Trackpad, it joins my repertoire of app launching, along with the Applications stack, Spotlight, and LaunchBar. Not always as smooth as advertised though.
  • AutoSave, Versions, etc.: Very helpful. ‘Nuff Said.
  • Resume: Usually very useful, for when I have a bunch of documents open in Preview, but can be annoying at times. Sometimes the point of quitting an app is to clear out all the windows. It’s a bit more annoying when the files take a while to load, as they might when launching QuickTime. But very useful after a reboot.
  • Mail: Great new interface, no loss of functionality—great recipe.
What happens is that OS X is less of a new OS, and more of a new paradigm. With the further integration of iCloud, it definitely fits this role. That’s also part of the reason why it’s $29.99—a great price for a preview of the future of computing. And yes, I honestly believe that.

iOS 5

  • Notifications: This one was a long time coming. Predicted by rumors for months, this is probably the best way to do notifications in a mobile platform. Very well done.
  • Twitter: I don’t use Twitter. I don’t get Twitter. …
Logo of WebKit framework

WebKit

  • Safari: The tabs are frankly a bit ugly, but the rest of the stuff is awesome. I’ve been a proponent of WebKit since the original iPhone. I love Safari Reader on the desktop, and I’m glad they brought it to iOS.
  • Reminders: Everyone needs this. The problem with To-Do lists though is forgetting to actually use them. Not sure what Reminders is going to do for that.
  • Camera: How do I up the volume in camera mode…? Actually, the features are really nice. If the iPhone 5 bumps the camera specs a bit, it could become a serious competitor to higher-end point-and-shoots, or maybe even some dSLRs…?
  • The New Keyboard: The keyboard on the original iPad always seemed just a little bit too small. I like being able to split the keyboard, but can’t help thinking that simply typing with my thumbs might not be the most efficient. Of course, this isn’t an issue that can be fixed overnight. Why couldn’t the screen have been just a tiny bit bigger…?

iCloud

Actually not sure what to think about this yet. The features look compelling enough, but without having half a dozen Apple devices not sure how well this’ll work. And plus, some companies, schools, etc. might block anything besides in-house cloud services, so its practicality might be limited. We’ll see.

First Impressions

So, that’s some initial commentary. I kept them to short blurbs for a reason—they’re first impressions. Incidentally, for developers, first impressions are absolutely vital. So, what are your thoughts? Post them in the comments below.

What’s in it for us?

Well, all the new APIs must mean something. What happens, though, is that Lion is literally bringing the iOS design paradigms to the desktop. Which means that user interfaces can be re-thought. Instead of simply relying on individual mouse clicks, gestures are now a now interface interaction method. This allows for much more fluid interfaces. What happens is that the design of user interfaces now takes prominence. Always emphasized with iOS, this design-based nature will trickle down to OS X. These interactions are visible in the new Mail, Safari, and iCal (^^). Sometime there will no longer be a single pair of coordinates for a mouse pointer—there will only be multi-touch and gestures. That is the future. And that is what developers must work for.

Supplement: CS193P


Stanford University has offered the CS193P class for a few quarters now. It has become the ubiquitous source of beginning iPhone programming material for many people. The lectures are filmed and uploaded to iTunes U, and they are now available in 720p HD video. However, the lectures, which are the only option for non-enrolled students, are rather impersonal, and sometimes move too quickly (in my opinion). I have learned a lot from them, but I don’t think they’re the only source. In fact, I find that they are more helpful once I got the basics down. Nevertheless, there are real gems, and so I will be occasionally referring links as supplementary material.

To access the lectures:

  1. Launch iTunes and head into the iTunes Store (don’t worry, all the lectures are free).
  2. Click on iTunes U on the black bar near the top of the storefront.
  3. At the time of this writing, the lectures were under Staff Favorites. Click on the link, and you’ll be led to the main listing.

    CS193P Fall 2010 Lectures Listing

    iTunes Listing

Direct link (will open iTunes, if it is not already running):
http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewPodcast?id=395605774

The lectures are available for streaming; alternatively, you can download them just like regular songs from iTunes. Note that file sizes are around 500MBs for the SD version and around 700MBs for the (linked) HD version.

The slides can be downloaded from the main website, listed above, as well as the sample code.

Objects (Part 1): Splitting Classes Into Multiple Files


This is the first in a multi-part series that will talk about the fundamentals of objects. If you’re still keeping track, I suppose these would all fall under Lesson 6: Objects.

In Lesson 3, we began a simple overview to object-oriented programming. Now, we’ve covered the major portions of the basic language—what is “plain C.” There are other topics, such as structs, arrays, and a slew of other rather obscure topics. Some of these are enclosed or remade in the code the Apple provides for free; others will be discussed as necessary. For now, we will start venturing into the exciting world of objects—and they really are exciting.

As part of our calculator, we will allow the calculator to operate on regular values, as well as fractions. For the sake of demonstration, we will begin by creating Fraction objects.

Creating the Test Code

Create a new Xcode project. In the New Project window, choose “Application” under Mac OS X from the left side, then choose “Command Line Tool” from the top right, and make sure the “Type” is set to Foundation. Click Choose, and save it as “FractionDemo” anywhere you choose. In the File List, load FractionDemo.m, and enter the following code:

#import "Fraction.h"
#import 

int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    Fraction *myFraction = [[Fraction alloc] init];

	// Set myFraction to value of 2/5
	[myFraction setNumerator: 2];
	[myFraction setDenominator: 5];

	// Display the value of myFraction
	NSLog(@"myFraction has a value of: ");
	[myFraction display];

	[myFraction release];
    [pool drain];
    return 0;
}

Here, you can see that in our main code body, we create an object of type Fraction, and call it myFraction. Ignore the asterisk (* for now; it is a sign that you are actually creating a pointer…that’s an advanced topic that will be further explored later). You set myFraction to the value returned from the standard alloc/init method call.

Next, we call the methods setNumerator: and setDenominator: and pass both integer values; these methods will set the appropriate values of the Fraction object we’ve created. We then send another message call for myFraction to display itself (or so we assume, based on the method name—make sure to write descriptive method names). Then we release our object—don’t worry about the memory management for now.

Now, we will create the actual Fraction object itself.

Creating the Fraction Class

In Xcode, Go to File > New File (⌘N). From the left, choose Cocoa Class under Mac OS X, select Objective-C class from the top left, and make it a Subclass of NSObject. Click Next, and set the following parameters:

  1. Set the File Name to be “Fraction.m”. Note that the “.m” part is automatically added; just type “Fraction”, without the quotes, making sure that the “F” is capitalized. By convention, class names are capitalized.
  2. Make sure that ‘Also create “Fraction.h”‘ is selected.
  3. Leave the default settings for the other fields. Add to Project should display “FractionDemo,” the name of your project, and in your Targets window, the checkbox to the left of the “FractionDemo” entry should be selected.

Click “Finish”. In your File List, you will see two new files: “Fraction.h” and “Fraction.m.” Select Fraction.h, and enter the following code:

#import <Foundation/Foundation.h>

@interface Fraction : NSObject {
	NSInteger numerator;
	NSInteger denominator;
}
- (void)setNumerator:(NSInteger)value;
- (void)setDenominator:(NSInteger)value;
- (void)display;

@end

Here we define two instance variables, called “numerator” and “denominator”. They are defined as type NSInteger; this is identical to the standard int type; there’s really no difference. My personal preference is NSInteger.

Next, we define the methods that we call in the main() method. There should not be anything new here, if you’ve read through Lesson 3.

In Fraction.m, enter the following code:

#import "Fraction.h"

@implementation Fraction
- (void)setNumerator:(NSInteger)value {
	numerator = value;
}

- (void)setDenominator:(NSInteger)value {
	denominator = value;
}

- (void)display {
	NSString *numeratorString = [[NSString alloc] initWithFormat:@"%d", numerator];
	NSString *denominatorString = [[NSString alloc] initWithFormat:@"%d", denominator];
	NSLog(@"%@/%@", numeratorString, denominatorString);
	[denominatorString release];
	[numeratorString release];
}

@end

Chewing through this code, the first two methods should not present anything new. The last method does warrant some discussion, however.

If you refer back to Lesson 3, you’ll notice that we defined the display method (we called it showResults there) as

- (void)showResults {
	NSLog(@"This is a fraction with a value of %d/%d", numerator, denominator);
}

Our display method shows a different way to do this. First, we highlight NSString’s initWithFormat: method, which works like NSLog() does, except that instead of outputting, it is saved as a string. In the actual NSLog(), we use the %@ format specifier, which takes an NSString as an argument. Finally, we have to release the NSStrings that we’ve created…again, don’t worry about the memory management at the moment.

If we Build and Run now, we get the following output:

myFraction has a value of:
2/5

This is exactly what we’re looking for.

You’ll notice that we haven’t really done anything new since Lesson 3. In fact, that is true, except that we have created a Fraction class in separate files. Looking back over the code entries, the bold lines show where the dependencies lie—in a class’s .m file, it #imports the correspond .h (known as the ‘header’) file. In any file that uses the class you’ve created, you also need to import the header. Here, you’ve made it easier to maintain a larger project; as we add more classes, you won’t be working with one gigantic file.

Extension 5: The switch Statement


The switch() statement is used in place of a chain of if()else if()else if()else if()else construct, where such a chain does not lead to very readable, follow-able code. The switch() statement is designed for this situation. Here is the general format:

switch(expression or variable)
{
     case value1:
          // Program statement
          // Program statement
          ...
          break;
     case value2:
          // Program statement
          // Program statement
          ...
          break;
     case value3:
          // Program statement
          // Program statement
          ...
          break;
     ...
     case valueN:
          // Program statement
          // Program statement
          ...
          break;
     default:
          // Program statement
          // Program statement
          ...
          break;
}

The expression value in the parentheses at the beginning of the statement is compared to each of the values, and when one of them matches, the following code (note the colon, and the lack of braces around each case), the code below is executed. It then breaks out of the rest of the switch, to avoid executing the rest of it (“overflowing” into the code for the next condition). This can sometimes be used intentionally, but for most of the time make sure to use the break; statement.

If none of the conditions match (the else of an if()else block), the code under the default condition is executed.

The following is an example of a switch() statement and the equivalent if()else block:

// This is an example of a switch statement.
#import <Foundation/Foundation.h>

int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

	NSString *operator = [[NSString alloc] init];     // We will talk in depth about NSString later on down the road.
	// Assume operator has been initialized to a valid value
	// Valid values for operator are @"+", @"-", @"*", and @"/"

	switch (operator) {
		case @"+":
			NSLog(@"Operator is for addition.");
			break;
		case @"-":
			NSLog(@"Operator is for subtraction.");
			break;
		case @"*":
			NSLog(@"Operator is for multiplication.");
			break;
		case @"/":
			NSLog(@"Operator is for division.");
			break;
		default:
			NSLog(@"Unknown operator.");
			break;
	}

    [pool drain];
    return 0;
}

This code should be rather self-explanatory; operator is compared to the values after each case, and if one of them matches, the executes the corresponding NSLog and breaks out of the switch. If none of them match, then it hits the default statement.

The equivalent if()else block follows:

// This is an example of a switch statement.
#import <Foundation/Foundation.h>

int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

	NSString *operator = [[NSString alloc] init];
	// Assume operator has been initialized to a valid value
	// Valid values for operator are @"+", @"-", @"*", and @"/"

	/* Note that NSString actually has a comparison method, and that
	   this method of comparison is not guaranteed to work. We are
	   overlooking that at the moment for the sake of education. */
	if (operator == @"+")
		NSLog(@"Operator is for addition.");
	else if (operator == @"-")
		NSLog(@"Operator is for subtraction.");
	else if (operator == @"*")
		NSLog(@"Operator is for multiplication.");
	else if (operator == @"/")
		NSLog(@"Operator is for division.");
	else
		NSLog(@"Unknown operator.");    [pool drain];
    return 0;
}

This code does the same thing as the switch statement above (bar the comment in bold).

The switch() statement is makes more logical sense, but some people find it annoying. It all comes down to a matter of personal preference. No big deal.

BTW less than a month after the previous milestone we are at 2000 views! Thanks to everyone who stopped by, and I hope to see you back!

Postscript: Wikipedia has a nice article on controlling program flow. It is a bit dense, but for anyone who is interested, go check it out! And while you’re there, you might as well see the article on the switch statement as well.

iOS 4.2 Beta 3 Now Available!


It’s been a month or so since beta 2…but beta 3 came out (yesterday). I love new software; I usually don’t consider myself a beta tester, but in this case I can make an exception.

A few novel features include new wallpaper and new SMS ringtones.

However, it appears that the native YouTube app has lost AirPlay capability. Apparently AirPlay is not native to movie files, but can be enabled or disable by the developer. We’ll see what this means.

The download awaits.

Objective-C Lesson 3: Object-Oriented Programming


When object-oriented programming arrived in the programming world, it was considered a savior of software by some and yet another foolish experiment by others. Regardless of the perspective, we need to define some basic concepts and terminology before we begin

A Thing

An object is a thing. In the real world, you have “things,” all of which have certain properties. For example, you probably have a car—a “thing.” The car has properties, such as paint color, total mileage, make, model, and year. You can also do things with the car, or have something done to it—for example, you can drive twenty miles in the car, or wash the car.

In an object-oriented program, your specific car is an instance of a class, generally called Car. A class is the definition of the object, and in most cases can be thought of as a “factory” for its instances. A class can create many instances of the same type of object, although they have to have different names. An object is simply a variable, but it can be (and usually is) of a custom type.

Instance Variables and Methods

As mentioned before, your car, and any other car, has certain properties that are potentially unique to that specific instance. These properties are known as instance variables, or ivars for short. Instance variables are variables, of either the standard data types, or of any other object, but they are private to the object—that is, every single instance of Car has its own identical set of instance variables; although the variables may be of the same type and number, they can (and usually do) contain different values across different instances.

A method is the proper term for a function, or simply a piece of code that is called upon to perform some action. In Objective-C, there are two types of methods—class methods and instance methods. Class methods are performed directly on the class that an object belongs to—for example, a class methods might ask the car factory how many cars it produced the previous year. Instance methods are performed on specific instances of a class—for example, you might ask one specific car to drive twenty miles, or you might wash one specific car; you wouldn’t do those things to the entire factory. Instance methods affect the state or condition of the object. Just like two identical cars adopt different characteristics over their lifetime, different instances of Car can take on different traits as well.

Message Objects

In Objective-C, there is a specific syntax for calling methods:

[ClassOrInstance method];

The method call begins with an open bracket. This is followed by the name of the class or instance, depending on whether the method belongs to a class or instance. This is followed by a space, and then the name of the method. This is followed by a closing bracket, and the all-important semicolon.
In more formal terminology, the following message call might be described as

[receiver message];

The meaning is the same.

Sample Program

Now, with the theory cleared up, we can move on to our first program involving classes.

Program 3.1

// A simple implementation of a Fraction
#import <Foundation/Foundation.h>

int main (int argc, const char * argv[]) {
	NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

	int numerator = 2;
	int denominator = 5;
	NSLog(@"This is a fraction with a value of %d/%d", numerator, denominator);

	[pool drain];
	return 0;
}

The output is

This is a fraction with a value of 2/5

In Program 3.1, we defined a numerator and denominator variable, and set them to integer values. We then printed the result of this simple fraction.

This program is short and condensed, and seems to be pretty simple—and it is. But what if we had a hundred fractions that we wanted to store? We’d have to keep track of two hundred variables. And performing operations on those variables would not be any easier.

As a matter of fact, Program 3.1 is not a true object-oriented program. It is still written using C-style code. We have not created any objects in the code; our Fraction object still exists only psychologically.

Program 3.2 presents the exact same functionality, except that we actually define this object in code. We then refer to the object as Fraction throughout the program. Don’t worry if it looks daunting; an explanation follows.

Program 3.2

// A Fraction class
#import <Foundation/Foundation.h>

//———————— Interface ————————

@interface Fraction : NSObject
{
	int numerator;
	int denominator;
}

- (void)showResults;
- (void)setNumerator:(int)n;
- (void)setDenominator:(int)d;

@end

//———————— Implementation ————————

@implementation Fraction

- (void)showResults {
	NSLog(@"This is a fraction with a value of %d/%d", numerator, denominator);
}

- (void)setNumerator:(int)n {
	numerator = n;
}

- (void)setDenominator:(int)d {
	denominator = d;
}

@end

//———————— Main Program ————————

int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    // Create an instance of Fraction
	Fraction *myFraction;

	myFraction = [[Fraction alloc] init];

	// Set myFraction to 2/5
	[myFraction setNumerator:2];
	[myFraction setDenominator:5];

	// Display the value of myFraction
	[myFraction showResults];

	// Clear up memory
	[myFraction release];

    [pool drain];
    return 0;
}

The output is

This is a fraction with a value of 2/5

Code, Demystified

Program 3.2 is divided into three logical sections. These are known as the interface, implementation, and program section, respectively.

The interface section (delineated by @interface in the code) provides basic program-wide definitions, the implementation section (delineated by @implementation) provides the implementation of the methods, and the program section contains the main code that does something.

The @interface Section

Every class in Objective-C has a single parent, or superclass, from which the class inherits. Next, you have to declare the instance variables that belong to the class. Finally, you declare the methods, or actions, that the class can perform. This is all done in the @interface section, which looks like this:

@interface ClassName : ParentClassName
{
	instanceVariableDeclarations;
}
methodDeclarations
@end

Remember that the compiler ignores spaces, so you may put line breaks and spaces anywhere within the code above.
By convention, the name of a class begins with a capital letter, as in the Fraction class.

You can tell that our Fraction class is a subclass of NSObject, which is the root object that almost everything else inherits from, directly or indirectly. NSObject is declared in the Foundation files which you imported.

Fraction contains two instance variables; both are ints. They are called instance variables because every instance of Fraction creates a new set of these variables, unique to that specific instance. So, FractionA’s numerator is a different variable than FractionB’s numerator. Objective-C automatically keeps track of this for you.

Currently, our Fraction class declares (and later implements) three methods. All are instance methods, as noted by the minus sign () preceding each method name. A class method is delineated by a plus sign (+).

Before we discuss the method declaration, we must remember than an object is considered a “black box.” Ideally, objects encapsulate, or hide, their instance variables, from anything except itself. The object exists as a single entity, and anything that works with the object does not need to know, and should not know, about the object’s inner workings. Therefore, we need to declare specific methods to set the variables, because the program should not directly manipulate them. We also need a separate method to print the values, because, once again, the program should not be able to directly access the variables. This is a fundamental concept in Objective-C, and is observed throughout the libraries and code.

The Fraction class defines three methods, all of which return nothing. The value in parentheses before the method name specifies the return type of the method. void is programming parlance for “nothing,” or nil. Any data type or object can be a return value; a method might return a float, int, or another Fraction, as illustrated by the following methods:

- (int)numerator;
- (float)divide;
- (Fraction *)randomFraction;

The asterisk after the Fraction is used to delineate a pointer; this is not an important concept at the moment. For now, simply remember that anytime you create an instance of a custom object, the name of the instance should be prefixed with an asterisk.

All of these methods must return a value somewhere in the method. Just as main returns 0 at the end, these methods must return an int value, a float value, and another instance of Fraction, respectively. The compiler will complain if you do not return a value.

The latter two methods declared in Fraction return no value, but they do each take an integer value as an argument. In the case of setNumerator:, the name of the argument is n. This name is arbitrary, as long as it follows the standard naming conventions, and is used only within the method to refer to the argument. The argument itself exists only within the method; you cannot access n anywhere else in Fraction.

Arguments are values that are passed into a method, which the method would not be able to obtain otherwise. For example, setNumerator: requires a value to set to the numerator, but it would not receive a custom value without an argument.

Note the syntax of these method declarations. The method name begins with the minus or plus, signifying the method type. This is followed by the return type in parentheses, the name of the method, and a colon. This colon is followed by an argument type in parentheses, a name for the argument, and a semicolon. In a method that takes an argument, the colon is considered part of the method name.

A method can take multiple arguments; they are delineated by a space, a new section of the method name, another colon, an argument type, and name. This will be covered in a later chapter.

The @implementation Section

In the implementation section, you define the code that each method implements. The general appearance of the @implementation section is similar to this:

@implementation ClassName
	methodDefinitions;
@end

In the implementation of Fraction, you also declare the method types and names, followed by an open brace. Between the opening and closing brace, you insert the code that the method will execute when it is called.

The program Section

In this program, the main program section contains the all-important main function that is the first thing to be executed.

In Program 3.2, we first create an instance of Fraction:

 Fraction *myFraction;

Again, don’t worry about the asterisk. From a technical perspective, it says that myFraction is a pointer to a Fraction.

Now that you’ve created an object “container” to store a Fraction, you have to actually create a Fraction to fill that space. You do that in the next line,

myFraction = [[Fraction alloc] init];

In this line, you call the alloc method on Fraction; alloc is a class method. Although you never defined the alloc method, it is inherited from NSObject. Inheritance will be discussed in a later lesson.

After you allocate a Fraction, you have to actually initialize it. Therefore, you pass the value of the alloc method to NSObject’s init method, and the resulting Fraction is assigned to myFraction. This nested sequence of messages is used almost every time you create a new object.

Next, you set the values of myFraction to 2 and 5 by using the proper method calls.

[myFraction setNumerator:2];
[myFraction setDenominator:5];

You pass the integers 2 and 5 as arguments to the method. The method then takes these arguments and sets the numerator and denominator variables of myFraction.

You then call myFraction’s showResults method to print the value of the fraction.

We then free up the memory that Fraction uses by calling the release method:

[myFraction release];

This is a critical part of programming for iOS. Whenever you create a new object through alloc/init, you have to release it—in other words, every alloc/init call is balanced by a release call. Otherwise, the now-useless object will still sit in memory, taking up space; in a memory-constrained environment such as the iPhone, you want to use as little memory as you can.

Messaging Receivers

In every message, you send the message to a specific receiver—the object or class which implements the method. However, instance methods are sent to specific instances, so that the same method call to two different Fractions will result in two Fractions with potentially different values. For example,

[fraction1 setNumerator:2];
[fraction1 setDenominator:5];

[fraction2 setNumerator:3];
[fraction2 setDenominator:4];

Will result in two separate fractions, one with a value of 2/5 and another with a value of 3/4. Although you are calling the same methods on both, they are received by different objects, with their own set of numerator and denominator variables.

Data Encapsulation

As mentioned before, you shouldn’t directly access the instance variables of an object. Data encapsulation provides some security against people working with the class, to prevent them from tinkering with the inner workings. So in the main function, how would you access these values?

Generally, you access these values by writing special methods, known as getter methods (the set methods that we’ve already wrote for Fraction are known as setter methods; they are generally written in pairs).

The getter methods for the Fraction class look something like this:

- (int)numerator;
- (int)denominator;

- (int)numerator {
	return numerator;
}
- (int)denominator {
	return denominator;
}

It doesn’t matter if the method name is the same as the variable name; in fact, it is common practice.

Program 3.3 contains the main function that tests these new methods.

Program 3.3

int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    // Create an instance of Fraction
	Fraction *myFraction;

	myFraction = [[Fraction alloc] init];

	// Set myFraction to 2/5
	[myFraction setNumerator:2];
	[myFraction setDenominator:5];

	// Display the value of myFraction
	NSLog (@"The value of myFraction is %d/%d", [myFraction numerator], [myFraction denominator]);

	// Clear up memory
	[myFraction release];    [pool drain];
    return 0;
}

The output is

The value of myFraction is 2/5

Objective-C 2.0 introduces properties, which provide an easy way to create getter and setter methods. This will also be covered in a later lesson.

Shameless Self-Promotion


To get the word out, I’d generally rely on search engines. And I can’t afford to pay Google to get listed (and most of those ads aren’t exactly reputable anyway). So, here’s some shameless self promotion. I promise I won’t really do this much more. Feel free to not read this. You may want to entertain yourself elsewhere (I’d recommend Uncyclopedia).


Cups of Cocoa Cups of Cocoa Cups of Cocoa Cups of Cocoa Cups of Cocoa Cups of Cocoa Cups of Cocoa Cups of Cocoa

iPhone App Development iPhone App Development iPhone App Development iPhone App Development

iPhone Application Development iPhone Application Development iPhone Application Development

Programming for iOS Programming for iOS Programming for iOS Programming for iOS Programming for iOS

iPhone App iPhone App iPhone App iPhone App iPhone App iPhone App iPhone App iPhone App iPhone App

iPhone Apps iPhone Apps iPhone Apps iPhone Apps iPhone Apps iPhone Apps iPhone Apps iPhone Apps

Creating iPhone Apps Creating iPhone Apps Creating iPhone Apps Creating iPhone Apps Creating iPhone Apps

iPhone Programming iPhone Programming iPhone Programming iPhone Programming iPhone Programming iPhone Programming

Developer Developer Developer Developer Developer Developer Developer Developer Developer Developer Developer

iOS iOS iOS iOS iOS iOS iOS iOS iOS iOS iOS iOS iOS iOS iOS iOS iOS iOS iOS iOS iOS iOS iOS iOS

App Store App Store App Store App Store App Store App Store App Store App Store App Store App Store App Store

Programming Programming Programming Programming Programming Programming Programming

iPhone iPhone iPhone iPhone iPhone iPhone iPhone iPhone iPhone iPhone iPhone iPhone iPhone

iPod Touch iPod Touch iPod Touch iPod Touch iPod Touch iPod Touch iPod Touch iPod Touch

iPad iPad iPad iPad iPad iPad iPad iPad iPad iPad iPad iPad iPad iPad iPad iPad iPad iPad iPad iPad

Xcode Xcode Xcode Xcode Xcode Xcode Xcode Xcode Xcode Xcode Xcode Xcode Xcode Xcode Xcode

Objective-C Objective-C Objective-C Objective-C Objective-C Objective-C Objective-C Objective-C

Apple Apple Apple Apple Apple Apple Apple Apple Apple Apple Apple Apple Apple Apple Apple Apple

Cocoa Cocoa Cocoa Cocoa Cocoa Cocoa Cocoa Cocoa Cocoa Cocoa Cocoa Cocoa Cocoa Cocoa Cocoa

iPhone SDK iPhone SDK iPhone SDK iPhone SDK iPhone SDK iPhone SDK iPhone SDK iPhone SDK

Software Software Software Software Software Software Software Software Software Software Software

Object-Oriented Programming Object-Oriented Programming Object-Oriented Programming Object-Oriented Programming


😀

Format Specifiers


Format specifiers are the percent character, followed by a letter, such as %d or %f that tell NSLog or printf() to print the value or result of a variable, value, and/or expression.

Here is a list of C format specifiers:

Format Specifiers in C

Just think of them as types of placeholders, each designed to represent a different value.

Objective-C Lesson 2: Basic Variables


In almost all programs, values may change; these values are stored in variables, which, as the name implies, are designed to have varying contents as the program is used. We’ll dive right in with a sample program.

Program 2.1

// Introducing variables

#import <Foundation/Foundation.h>

int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

	int i;
	i = 1;
	NSLog (@"The variable i has a value of %d", i);

	i = 2;
	NSLog (@"The variable i now has a value of %d", i);

    [pool drain];
    return 0;
}

The output of this simple program is as follows:

The variable i has a value of 1
The variable i has a value of 2

Code, Demystified

Program 2.1 contains the same “boilerplate” code in the template that Xcode provides for you. It is still not necessary for now, so explanation will be deferred.
The first “real” line of the program introduces the concept of a variable.

int i;

This variable is declared to be of type int and with the name i. Before we talk about the variable type, we have to take about the choice of the variable’s name.

Variable Names

In C, all variable names (in fact, almost all names in general) must be made of lowercase and uppercase letters, digits, and the underscore character (_). The first character of the name must be a letter or underscore. Because Objective-C is a strict superset of C, the same rules apply.

Note that C and Objective-C are case-sensitive. A lowercase letter is not the same as a capital letter. Therefore, fraction, Fraction, FRACTION, and fractioN are considered four completely different names. As a result, programmers often use camel case to declare variable names of multiple words. Examples include aPairOfDice, lotsOfMoney, and someAddress.

Because of the wide variety of options available to you, make sure to choose descriptive variable names, such as taxRate instead of t. You can only thank yourself later on.

Reserved Names

The Objective-C language reservescertain words, so that you cannot use them as a name; in fact, some are reserved by C itself. For a complete list, check out this post.

Data Types

In program 2.1, the variable i was declared to be of type int. This means that i can only hold a whole-number value, without a decimal point—an integer. Integer values are one of four basic data types. The others are floating-point values, characters, and boolean values. Floating-point values are simply numbers that include a fractional portion, represented as a decimal, such as 5.2 and 10.0. Characters are any single character that you can type on your keyboard, such as ‘A’ and ‘@’ and few others. Boolean values are either true or false; in Objective-C they represented as YES and NO.

Beyond the basics, C also defines three “adjectives” to modify the size of variables. These are short, long, and unsigned. An integer declared to be short will take up less memory than a standard int, and a long will take up more space. You can also use the specifier long long to indicate even larger values, but in OS X and iOS the additional long makes no difference. unsigned is used for values that will never be negative; this effectively doubles the maximum (positive) value of a variable without doubling its storage requirement (because every single negative value can now be “mapped” to a larger positive value).

short and long cannot be used in conjunction with each other in the same variable, but unsigned, or its optional counterpart signed, may be used on any variable, short, regular, or long.

Initialization

After declaring a variable, you have to initialize it with a value; otherwise, the variable would be useless. You can do this in a single statement, along with the declaration:

int variable = 1;

Alternatively, you can declare the variable, and then initialize it sometime later (it does not have to be the next statement):

int variable;
// Some code
variable = 1;

Printing Variables

Program 2.1 introduces a few new concepts in the NSLog statements.

NSLog (@"The variable i has a value of %d", i);

The real magic happens with the %d. This is a format specifier, and tells NSLog that it should expect a variable of a certain data type, and to print the value of that variable. In this case, the type %d tells NSLog to expect an integer value, and it does receive i as an argument, which is an integer value. Therefore, NSLog looks for the value of i, and prints the integer value. This explains the output:

The variable i has a value of 1

In the next few lines, we set i to the value 2, and then use NSLog to print it.

Note that the specifier %i is also used to print integer values.

Program 2.2

// Arithmetic operations with variables
#import <Foundation/Foundation.h>

int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    int result;
	result = 10 + 20;
	NSLog(@"The sum of 10 and 20 is %i", result);

	result = 25 - 30;
	NSLog(@"The difference between 25 and 30 is %i", result);

	result = 8 * 9;
	NSLog(@"The product of 8 and 9 is %i", result);

	NSLog(@"The quotient of 8 and 5 is %i", (8 / 5));
	NSLog(@"The quotient of 8.0 and 5.0 is %.1f", (8.0 / 5.0));	[pool drain];
    return 0;
}

The output is:

The sum of 10 and 20 is 30
The difference between 25 and 30 is -5
The product of 8 and 9 is 72
The quotient of 8 and 5 is 1
The quotient of 8.0 and 5.0 is 1.6

Program 2.2 presents some interesting situations. To begin, we define an integer value, and name it result. We set result equal to 10 + 20. Then we have the NSLog statement print out the value of the variable result, and we use the integer specifier because the result is an integer. The next few lines does the same, but note that negative values are supported. Multiplication works as expected, but the last two NSLogs deserve some attention.

The first thing to note is that you can specify an expression as an argument to NSLog, not simply a variable. As long as the result is of the proper type, NSLog doesn’t care whether you specify an expression or a variable.

Next, note that the first division results in a value of 1. Obviously, 8 ÷ 5 ≠ 1, but this is not a mathematical error. Remember that the format specifier %i is responsible for printing integers. Also note that the values 8 and 5 are both integers. This is an example of integer division. Through integer division, only the whole-number portion of the result is reported—any fractional portions are discarded.

To get the accurate result, we have to use floating-point numbers. These numbers are only syntactically different from ints in that they include a .0 portion at the end—as in 8.0 and 5.0. To print a floating-point value, we use the format specifier %f. The .1 portion of the specifier tells NSLog to only print the first decimal point, and disregard any others that may follow. Here, we can see that the result is indeed 1.6.

  • Welcome

    My goal is to make CupsOfCocoa into a beautiful source for beginners to the iPhone platform to get started. Subscribe below for more, and stay tuned!

  • Contact Me

    If you need to contact me for any reason, feel free to send me an email.
  • The Giving Spirit

    If you've found this site helpful, would you consider donating a little sum? Any amount is appreciated...Thanks so much!

  • Roadmap

  • Enter your email address to follow this blog and receive notifications of new posts by email.

    Join 220 other followers

  • Back to the Past

    September 2020
    S M T W T F S
     12345
    6789101112
    13141516171819
    20212223242526
    27282930  
  • Time Machine

  • You count!

    • 622,769 views
  • Worldwide Stats

    free counters
%d bloggers like this: