Home > 2010 Fall DPS913 > Introduction to Objective-C for Seneca SCS students

Introduction to Objective-C for Seneca SCS students

September 9, 2010 Leave a comment Go to comments

This post introduces School of Computer Studies students to the Objective-C programming language.

.

The Objective-C programming language is used to create iOS and Mac OS X applications (also known as “apps”). Cocoa provides the programmer with a rich library of Objective-C classes, as well as an execution environment (aka “runtime”).

You enter this course with a good amount of knowledge and skills. You have done C++ programming, as well as Java and C# programming. Along the way, you did a good amount of SQL work.

Here is my “getting started with Objective-C” advice to you: Forget about what you’ve learned about the C++ language. Also, forget about what you’ve learned about the Java, C#, and SQL languages. Your past knowledge will just get in the way of what you must learn to quickly get comfortable with Objective-C.

You probably didn’t expect that, right? So now, if you’re thinking, “wow – what experience can I use?”, here’s what I suggest:

  • Know the C programming language – if you know C, you’re half-way there
  • Practice object-oriented programming techniques
  • Have the ability to learn quickly
  • Be curious, and a good problem-solver
  • Learn how to use the documentation effectively

.

The relevant history of Objective-C

Objective-C is an established language, and is just over 25 years old. It became more widely known with the rise in popularity of the Mac OS X, and more recently, the iOS platform devices.

The language was created by Brad Cox and Tom Love in the early 1980’s. Its design was influenced by the Smalltalk programming language, which was among the first languages to feature object orientation, dynamic features, and introspection/reflection.

How did it get to the Mac? Steve Jobs left Apple and founded NeXT Computer in 1985. Soon after, the operating system and development toolset was created, based on the Objective-C language, and on framework libraries created with it. These components became known as NeXTSTEP, and the “NS” initialization became a prefix for many of the classes in the library. In 1997, Apple Computer bought NeXT, and Steve Jobs returned to Apple. The NeXTSTEP operating system was reengineered into Mac OS X, and the NeXTSTEP libraries were reengineered into Cocoa.

Objective-C was developed around the same time as C++, but independently. The design of C++ was influenced by the Simula programming language, which is considered to be the first object-oriented programming language. (Java and C# are also influenced by Simula and C++ designs.) It must be emphasized that Objective-C is not based on C++. Their object models don’t match up, and the design philosophy is different.

The language is often described as “C with a small set of object-oriented extensions”. You’ll see why soon. For C programmers, it really is an easy to learn and use language.

.

Structure of a simple Objective-C program

In class, we will create our first app of the semester. (Guess what output it produces?) If you want to follow along here:

  1. Start Xcode, and choose to create a new project
  2. In the “Mac OS X” area in the left-side object browser, select “Application”, and then “Command Line Tool” in the right-side details pane; click the Choose… button
  3. Select a location to store your project, give it a name (I’ll call mine “OurFirstApp”), and click the Save button

Our project typically contains a number of source files, and resources like images and so on. The project is the compilation unit. This is very similar to the concept of a .NET project that you create in Visual Studio.

The left side of Xcode displays an object browser, titled “Groups & Files”. The project name (OurFirstApp) object is expanded by default, and shows folder icons for Source, Documentation, External Frameworks…, and Products. This structure doesn’t really mean anything; it is simply an organizational aid. Open/expand the Source folder icon, and you will see OurFirstApp.m. Click to select it, and it appears in the editor pane on the right side.

Our project’s entry point is the “main” function in this source code file – as you would expect in a C program. Let’s inspect this source code:

  • The #import statement does what #include does, but only once per library/framework in a project
  • The NSAutoreleasePool… and [pool drain… lines of code configure the Cocoa automatic memory management feature
  • The NSLog… statement calls the NSLog function, which causes output to be displayed on Xcode’s “console log” window

After examining this code, you should be relieved that it looks like C code, although there’s some new syntax.

How can you run your program? On Xcode’s Build menu, choose Build and Run (Command+R). Your program will compile, and run, displaying its output in an Xcode console log window. When you’re ready, you can then close the console log window (Command+W).

What else do we find in the “Groups & Files” object browser? The only interesting one is the External Frameworks icon – expand it, and you will see “Foundation.framework”. The External Frameworks branch shows you the frameworks (i.e. code libraries) that are imported into your project.

Let’s create another project, for the iOS. If you want to follow along here:

  1. In Xcode, choose to create a new project
  2. In the “iPhone OS” area, select “Application”, and then “View-based Application” in the right-side details pane; next, make sure that the “Product” dropdown list is set to “iPhone”; click the Choose… button
  3. Select a location to store your project, give it a name (I’ll call mine “FirstiOSApp”), and click the Save button

When you examine the left-side “Groups & Files” object browser, you’ll see a few more folder icons when compared to our first project. Expand the “Other Sources” folder icon, and you will see “main.m”, which is our project’s entry point (and includes the “main” function). Let’s inspect this source code:

  • The #import statement does what #include does, but only once per library/framework
  • The NSAutoreleasePool… and [pool drain… lines of code configure a Cocoa memory management feature
  • The …UIApplicationMain… statement calls the UIApplicationMain function, which creates the application object (from the Cocoa UIApplication class), and instantiates the delegate (which is an object – an instance of a class – that has methods that can be called from other objects)

If you don’t know what a delegate is, we will explain soon.

After examining this code, you should still be relieved that it looks like C code. Now, let’s examine your project’s code in more depth. Expand the “Classes” folder icon, and you will see four source code files, organized in pairs:

  • There is a .h and a .m source code file for the <appname>AppDelegate
  • There is a .h and a .m source code file for the <appname>ViewController

Objective-C is a header-based language. We declare our instance variables and method signatures in the .h interface file. We write the implementation code for those methods in the .m implementation file.

The <appname>AppDelegate is the delegate object that gets instantiated in the program entry point’s “main” function.

The <appname>ViewController is an object that has your custom logic code for a “view”; a view is typically a screenful of content in an iOS app.

Later, we will work with these (and other) source code files, and learn more about them.

How can you run your program? Build and run (using the menu choice or Command+R). Your program will compile, and run. For an iOS application, the iPhone Simulator will open, and your program will “install” there, and run. Without modifications, your program will simply display a grey-coloured screen. When you’re ready, tap/click the “Home” button on the simulator (the round button near the bottom), and then Command+Q to quit the iPhone Simulator. You can then close (Command+W) the console log window.

What else do we find in the “Groups & Files” object browser? Similar to the first example above, the Frameworks folder shows the frameworks that are imported into your project. The Resources folder has two files with “.xib” extensions, and a “.plist” file. The “.xib” files are known as “nib” files, and each is an archived (“serialized” in Java/C#) object graph of user interface objects. The “.plist” file contains app configuration data. We’ll learn more about these files later.

.

So, where does my code go? What code do I write?

You have just learned that the entry point for your app is the “main” function. And, you have just learned that the code that you write can be placed in the “main” function, or in the viewDidLoad method of the view controller object in the iOS app example.

So, where does my code go?

The bottom line is that your code goes in different source code files, depending on its use and purpose. Here are a few initial observations for writing an iOS app:

  • Write code in the <appname>AppDelegate when you want to set up the app’s initial execution environment
  • Write code in the view controller when you want to interact with the user
  • Write code in new classes that you create, to meet additional and customized needs
  • Use the project structure suggested by Xcode’s “Groups & Files” object browser to help you organize your source code files

What code do I write?

Many developers – especially this group, third- or fourth-year Computer Studies students – have experience with a code generation environment, like the .NET Framework when writing ASP.NET Web Forms apps (e.g a DataSet). Xcode, and the Objective-C and Cocoa environment, does NOT use code generators. You write the code yourself. Sometimes the Xcode project template provides code chunks and stubs, but there’s no code generation.

Classes are the containers for your code. As noted above, you write code in the existing classes (provided in the Xcode project/app template), or in new classes that you create. You end up writing two kinds of code:

  1. Overrides of existing methods that exist somewhere in the class and superclass hierarchy
  2. New methods that provide custom functionality, to work the way you want

These methods (overrides and new) gets called in two ways:

  1. Statements somewhere in your own code path
  2. Events that occur during the lifetime of the app (e.g. user interface actions, network events, etc.)

Understanding the concepts in this section are crucially important to your early success in this course. Later, you’ll learn more about the app lifecycle, but essentially, you need to realize that your main task is to just write a bunch of event handlers.

.

Objective-C is C with object-oriented extensions

As this section’s title states, Objective-C is C with object-oriented extensions:

  • Anything you can do in C, you can do in Objective-C
  • Objective-C is a fully-compatible superset of C
  • The extensions – the superset part – introduce some new syntax to you
  • Objective-C offers you dynamic features, where decisions can be made at runtime

.

The extensions include new types

All of the scalar C types are available to you in Objective-C. You will continue to use them. C structs are still available to you, and explicitly-expressed pointers (using the * symbol) are still used. However, all of the “pain points” in C types have been addressed by Objective-C types and Cocoa classes.

The Cocoa Foundation framework includes new types that you will use frequently:

  • id (a generic type for any kind of object)
  • BOOL (with constant values YES and NO)
  • NSString * (a rich and functional string type)
  • NSNumber * (an object wrapper for a C scalar int, float, or double)
  • NSArray * (which has elements that are objects of any type)
  • NSDictionary * (which is known as a hash table, or associative array, in other languages)

-and others-

Note the use of “NS” as a prefix for many of the classes. This prefix shows the “NeXTSTEP” heritage of the Cocoa framework and the Objective-C language.

Objective-C provides mechanisms – casting and conversion methods – that enable you to convert among types.

.

You create your own types when you write Objective-C code

The examples introduced earlier showed you that an Objective-C program starts like any other C program – in the “main” function of a code module. A typical iOS app will call the UIApplicationMain function, which creates the application object and the application delegate object in the Cocoa runtime. So, when launched, the Cocoa runtime is managing and orchestrating your app, and it enables the user to interact with your app. We’ll learn more about app startup, execution, and termination – the app lifecycle – later.

The important point here is that the “application delegate” gets created. This is the <appname>AppDelegate instance. It is an object – an instance of the <appname>AppDelegate class.

All other Objective-C code that you write is in the form of “classes” (aka your own “types”). Sometimes these classes inherit from the “NSObject” superclass, while other times they inherit from another superclass, such as one of Cocoa’s “controller” classes. Typically your code will create one or more instances of your class at runtime, during normal use.

As you would expect from an object-oriented language, your class includes state and behaviour – it can have instance variables, and instance methods. Additionally, class methods (aka “factory” or “convenience” methods, or “static” methods in Java/C#) can be defined.

.

Objective-C has some significant syntax differences

An experienced C++/Java/C# programmer, who is new to Objective-C, will be familiar with much of the C-like syntax, but will also observe some significant syntax differences. We will focus on two differences:

  1. Source code file structure
  2. Method declaration and use

.

Source code file structure syntax differences

As noted earlier, Objective-C is a header-based language. We declare our instance variables and method signatures in the .h interface file. We write the implementation code for those methods in the .m implementation file.

Let’s look at the following commented version of the FirstiOSAppViewController.h interface file:

  • The #import statement does what #include does, but only once per library/framework in a project; here, we import the UIKit framework
  • The @interface keyword marks the beginning of the class declaration (similar to “public class” in Java/C#)
  • The class name follows the @interface keyword, and then there’s a : colon, and the name of the superclass it inherits from
  • A curly brace block encloses the declaration of instance variables
  • Below the curly brace block, you can optionally declare some of your instance variables to be properties of the class
  • Also here, you would declare the signatures of your methods, which may include initializers (“constructors” in Java/C#)
  • The @end keyword marks the end of the class declaration
#import <UIKit/UIKit.h>

@interface FirstiOSAppViewController : UIViewController {
	// Instance variable declarations go here
}

// Property declarations for selected instance variables go here

// Method declarations also go here

@end

Now, let’s look at a commented version of the FirstiOSAppViewController.m implementation file:

  • The #import statement imports the class’ header
  • The @implementation keyword marks the beginning of the class implementation
  • Similar to above, the class name follows the @implementation keyword, but only the class name
  • If properties were declared in the header, they are implemented here
  • Then, the implementation of your declared methods follows, along with any desired overrides of superclass methods
  • The @end keyword marks the end of the class implementation
#import "FirstiOSAppViewController.h"

@implementation FirstiOSAppViewController

// If properties were declared in the header, they are implemented here

// Then, the methods (that were declared in the header) are implemented
// Additionally, you can implement overrides of superclass methods

- (void)viewDidLoad {
	// The following statement calls the superclass method of the same name
	// This is standard procedure for method overrides like this
	// It appears as the FIRST statement in all method overrides except dealloc
	[super viewDidLoad];
}

- (void)dealloc {
	// In this method, you perform memory management tasks
	// The following statement calls the superclass method of the same name
	// In the dealloc method, it appears as the LAST statement
	[super dealloc];
}

@end

.

Method declaration and use syntax differences

The implementation code you just saw above hinted at the other significant syntax difference – method declaration and use.

What’s with the dashes? The square brackets?

To help answer these questions, let’s create a method. It will take three string arguments. We’ll use Cocoa strings, which are instances of the NSString class. The method will simply concatenate the three string arguments together, using linefeeds, and return the result to the caller.

The following code shows how we declare it in Objective-C. It’s very different from how it’s done in C++, Java, and C#. The code has been wrapped so that is is clear and clean. Sometimes, in code samples that you see, or in code that you write, you will see the arguments aligned by the colons, to promote readability.

- (NSString *)makeFormattedLabelFromName:(NSString *)fullName
							 withAddress:(NSString *)streetAddress
						   andPostalCode:(NSString *)postalCode;

You should notice these differences:

  • It’s verbose – that’s OK, and encouraged, to make the method readable and self-documenting
  • It doesn’t look like C++/Java/C# method declarations, and there are no commas to separate the arguments – yup, that’s right

Let’s explain the other differences next.

When you declare a method, you decide whether it will be an instance method, or a class (i.e. factory, static) method. Many Cocoa classes offer you class methods for frequently-used tasks, and you can use the same approach. How do you declare the difference? With a minus sign, or a plus sign:

– Instance method

+ Class method

After the dash, you see the return type, using the familiar C-style cast syntax. The return type can vary:

void Returns nothing

id Returns an object that could be of any type

foo * Returns an instantiated “foo” object (our example above uses an NSString *)

Then, we have the method name.

  • It can be quite long, and in that situation, the method name is broken up into multiple parts, separated with colons
  • The method name includes the colons
  • The arguments are interspersed into the method name
  • Each argument includes the type (using the C-style cast syntax again) and the name

NOTE: The previous paragraph is critically important for the new Objective-C learner. The method name includes the colons. Therefore, if you were writing documentation for your new method, or looking in the documentation for an existing method, you would express the method name in the following way:

makeFormattedLabelFromName:withAddress:andPostalCode:

If a method does not have or need any arguments, then it won’t have any colons.

The Objective-C designers thought this would be a great way to create readable and unambiguous code, especially in methods that have many arguments. When you think about it, you will realize that they have a point. You know with certainty what the arguments are, and the method is somewhat self-documenting with respect to its meaning and usage.

We finish off the declaration with a semicolon statement terminator.

When implementing the method we do three things:

  1. Enter the method declaration statement; the easiest way to do that is to type a dash (or plus), the first few characters of your method name, and press the Esc key (on the keyboard); the autocomplete list will show your method, which you can then highlight and select (by pressing Enter)
  2. Type an opening curly brace {, and the editor will (should) add the closing brace } below
  3. Add your custom code inside the curly brace block
  4. If your method has a return type (i.e. it is NOT void), make sure you return an object of the type somewhere in the code path

Let’s look at a simple implementation of this method:

- (NSString *)makeFormattedLabelFromName:(NSString *)fullName
							 withAddress:(NSString *)streetAddress
						   andPostalCode:(NSString *)postalCode {

	// Custom code/logic could go here

	return [NSString stringWithFormat:@"\n%@\n%@\n%@",
			fullName, streetAddress, postalCode];
}

The first line (or three lines) is the same as the declaration (except for the ; becoming a { ). The “return” statement is returning a Cocoa string. (Trust me on this. We’ll discuss calling a method next.)

Now, let’s call this method from somewhere else in the code path.

Let’s assume that when the app launches, it will simply write a nice formatted address label to the Xcode console log. The “viewDidLoad” method is called by the Cocoa runtime when the user interface appears on the iPhone screen. This is the ideal place to write code that will make something happen. Here is the edited implementation of the viewDidLoad method. Again, the wrapping and extra white space is used to help present a clear and clean idea to you.

- (void)viewDidLoad {
	[super viewDidLoad];

	// Call the method...
	NSString *myLabel = [self makeFormattedLabelFromName:@"Peter McIntyre"
											 withAddress:@"Toronto, ON"
										   andPostalCode:@"M3J 3M6"];

	// Write the result to the Xcode console log...
	NSLog(@"%@", myLabel);

}

If you’re lost already, let’s explain what’s going on.

We declare an instance of an Cocoa string, called myLabel. By convention, use a lower-case letter to start with, and camel casing for the remaining words.

When calling a method, known as “sending a message” in Objective-C, we use the following general syntax:

[ receiverName methodName:withData andAnotherArgument:withItsData ] ;

Note the following:

  • Messages (method calls) are wrapped in square brackets. Nesting is allowed.
  • The receiverName is the object (instance) that will be receiving the message.
  • The method name follows. If the method takes an argument, add its data, and if there are more arguments, use white space to separate arguments, and add the argumentName:itsData pairs.

Note that we do NOT use “dot” notation when calling a method, as you would in Java/C#. (For example, in C#, you may call a method similar to the above using the syntax “this.makeFormattedLabel(“name”, “address”, “postalcode”);”. We do NOT use “dot” notation here.

Note: Soon, you will see Objective-C syntax that DOES use “dot” notation, but only for two scenarios:

  • When using property accessors
  • When using C structs

Incidentally, in our example, we are calling a method which is declared and implemented within our class. In Objective-C, the “self” name is used to declare to the current instance of this object. (Java/C# use the “this” name.) So, the receiverName is “self”.

Then, the method takes three Cocoa string arguments. A Cocoa string has a @ prefix (whereas a C string won’t).

The last statement writes the myLabel result to the Xcode console log. To do this, the NSLog function is called. It takes a Cocoa string argument (we’re just going to call these “strings” from now on), and the function uses printf-style formatting. The %@ format specifier is new to you, it is actually a syntax shortcut that calls a “description” method, which for most objects, returns a string.

.

Object types, pointers, scalar types, structs, and constants

As you have learned, Objective-C is C with object-oriented extensions. Anything you can do in C, you can do in Objective-C, which is a fully-compatible superset of C.

You have the C scalar types of int, char, float, and double available for use. If you want, you can still use C data structures like arrays and strings, although you will typically prefer the Cocoa versions. Pointers work the same in Objective-C as they do in C. Structs work the same too. So do constants and macros.

The big difference is that Objective-C enables the use of objects:

  • A Cocoa object is essentially just a C struct, with some code attached
  • All Cocoa object names are pointers to the memory used by the instantiated objects
  • The declaration is explicit – you MUST include the pointer reference asterisk (it isn’t hidden, or built in, as in Java/C#)

Many of the objects you will create in the first few weeks will be instances of Cocoa classes that typically begin with a “NS” or “UI” prefix. For example, see the following:

NSString *myName = …

NSArray *addressFields = …

UILabel *lblTitle = …

UIButton *btnDoSomething = …

The Cocoa frameworks also include a number of other language elements, including C structs, that also include the “NS” prefix. These are not objects, and are not declared using the * pointer syntax. Therefore, one of the skills that you’ll learn early on is the proper and efficient interpretation of developer documentation. Until then, here are a few C struct examples:

NSPoint upperLeftOfScreen = …

NSRect myAreaOfTheScreen = …

NSRange partOfMyName = …

.

Declaring, instantiating, and using objects

There are two ways to declare and instantiate an object:

  1. In your code, you both declare and instantiate the desired object (we saw this above, “myLabel”).
  2. In an app with a user interface (like an iOS app), the Interface Builder development tool helps you define and declare objects, which will get instantiated when the user interface is launched. If you want access to a user interface object (e.g. a text field), you also declare it in your code, and then connect them together in Interface Builder. More about that later.

We saw #1 above, and that’s what we’ll focus on in this section. We’ll look at #2 later.

Assume that we have already created a “model” class, called Student, which inherits from NSObject (in other words, NSObject is its superclass). It encapsulates state information for the data you’d expect (name, address, student ID, faculty, and so on). It also encapsulates behaviour (initialization, reporting, and so on). We’re going to use instances of Student elsewhere in our code.

We’ll get started by instantiating some Student objects in our controller, <appname>ViewController.

Our first task is to ensure that the desired class is in scope. For an iOS app, the Foundation and UIKit frameworks are always in scope (see the <appname>App_Prefix.pch source code file). To use our own classes, we must import their headers where they’re being declared and used. Therefore, use the #import “Student.h” syntax in the .m implementation.

Now, we can get to the task of declaring and instantiating objects.

In our first example, we declare a new student object:

// Declare a pointer, just like you do in C
Student *firstStudent;

At this point in time, the firstStudent name/identifier exists. However, no memory has been allocated for its use, and its initial state has not been determined.

Let’s look at a more typical example. Notice the nested message syntax, which was hinted at earlier.

// Declare and instantiate
Student *secondStudent = [[Student alloc] init];

This is better. We now have a ready-to-use Student object, secondStudent. Notice how this is done:

  1. The Student class is sent a message “alloc”. The “alloc” method is a class method of Student’s superclass, NSObject. It returns a new instance.
  2. This new instance is then sent the “init” message. The “init” method is an instance method of NSObject, and is typically implemented (overridden) by a subclass (i.e. our own Student class). Its purpose is to initialize the object’s instance variables (i.e. its state information) with reasonable initial values.

Incidentally, if reasonable initial values are not provided for in your code, the Cocoa runtime sets binary zeroes as the initial values.

At this point in time, secondStudent is ready to use. We can access its instance variables (i.e. its state), whatever they are. We can also send messages to it (i.e. call its methods), whatever they are.

You may be thinking about initialization… What if we want our own initialization? Perhaps where we pass in initial values? Well, we can override init, and also provide additional initializers. The naming convention for additional initializers always uses “init” as the prefix. Later in the course, we’ll learn about the details of overriding init, and how to write additional initializers, but in the following example, all we want to see is how a custom initializer is used when declaring and instantiating a Student:

	// Use a custom initializer
	Student *thirdStudent = [[Student alloc] initWithName:@"Peter"
												  faculty:@"FIAT"
													andID:123456789];

The thirdStudent object is ready-to-use with the known and supplied values.

Is there another way to create Student objects? Yes, using class methods (if they are available). In the last example, below, we’ll call a class (aka “convenience”, or “factory”, or “static”) method that returns a ready-to-use object:

	// Create a new Student with a class method
	Student *fourthStudent = [Student newSCSStudent];

In any of the four examples above, we can now use the objects that we created. Here are a few usage examples:

	// Use the objects we just created...

	// Make a new object from a copy of an existing object
	// The "copy" method is in NSObject, which is Student's superclass
	Student *fifthStudent = [firstStudent copy];

	// Tell us what the name of thirdStudent is; stuName is a getter method
	NSLog(@"Student ID is %d", [thirdStudent stuName]);

	// Update the name of fourthStudent; setStuName is a setter method
	[fourthStudent setStuName:@"Evan"];

That wraps up our look at declaring, instantiating, and using objects. As noted above, we’ll learn later about overriding init, and writing our own custom initializers.

.

Instance variable accessors (getters and setters), and properties

In the code sample above, we saw a getter: [thirdStudent stuName]

We also saw a setter: [fourthStudent setStuName:@”Evan”]

As you know from other platforms and languages, you write getters and setters when you wish to use an object’s instance variables externally (i.e. when you are working with an instance of the object). In Objective-C, you follow these guidelines for writing getters and setters:

Writing a getter method:

  • The method name must match the instance variable name – a “foo” instance variable will have a getter method named “foo”
  • The method will be an instance method (i.e. it starts with a minus sign)
  • Its return type must match the instance variable type

Writing a setter method:

  • The method name must be prefixed with “set“; additionally, the first character of the instance variable name is uppercase (for example, a setter for the “bar” instance variable would be named “setBar”)
  • The method will be an instance method
  • Its return type is void

As an alternative, the Objective-C property syntax helps eliminate the clumsy getter and setter syntax for typical usage scenarios. If you decide to use the property syntax, and you should, there are two coding steps required – one is done in the .h interface, and the other in the .m implementation.

In the .h interface file, decide which instance variables are to be exposed as properties. Then, below the curly braces, declare them as properties, using the following syntax:

    @property (nonatomic, copy) NSString *stuName;
    @property (nonatomic, copy) NSString *stuFac;
    @property int stuID;

In the syntax above, you will see these features:

  • Each property starts with the @property keyword
  • For objects (i.e. not scalars), a list of object attributes/behaviours is next, enclosed in parentheses
  • Finally, the syntax used to declare the instance variable earlier is repeated

Nonatomic means “not multithreaded”, which is suitable for our entry-level iOS and Mac OS X apps. Copy has memory management meaning (covered later); here it means that the property’s data is a copy of whatever data that is assigned to it. Note that the C scalar type int doesn’t get any object attributes/behaviours.

In the .m implementation file, after the @implementation statement, use the following syntax, which causes your property’s accessors to be created:

    @synthesize stuName, stuFac, stuID;

By default, properties are mutable – read/write. This is the case even if you declare the property as an immutable type, like NSString.

What if you want custom configuration for your property? Well, you simply implement the custom getter or setter in the .m implementation file. (You do not have to declare the method name in the .h interface.)

The other feature that properties enable is the use of “dot” syntax for the accessors. Instead of using syntax that explicitly sends an instance a message (e.g. [ secondStudent stuName ]; ), we can use dot syntax – “instanceName.propertyName”, as shown below:

    // Using property accessors, with the "dot" syntax
    NSString *newString = secondStudent.stuName;
    fourthStudent.stuFac = @"FIAT";

When coding, always use “instanceName.propertyName” syntax. In other words, don’t use only the “propertyName” to refer to the property. (Why? To remove ambiguity. If you use only “propertyName” within the source code class module, it is actually referring to the instance variable. Outside – that is, when another object is working with an instance of this object – the “propertyName” alone has no meaning.)

.

Our final introductory language feature – dynamism

Later, but soon, we’ll cover a few of the dynamic features of Objective-C. For now, you should be aware that it’s possible to use dynamism to, for example, dynamically add methods to a class (even base Cocoa classes), or to use run-time information and state for introspection and decision-making. Very powerful, and very useful.

.


Advertisements
Categories: 2010 Fall DPS913
  1. No comments yet.
  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: