Learn Objective-C: Day 4

Learn Objective-C: Day 4

Tutorial Details
  • Difficulty: Beginner
  • Technology: Objective-C
  • Completion Time: 20 - 45 Minutes
This entry is part 4 of 6 in the series Learn Objective-C

Welcome to part four of this series on Objective-C. So far, we’ve looked a lot at theory and the principles and functionality of the language to get a good idea of how it works. Today, we will be making a simple class similar to the car example we looked at in previous parts of this series. Our class will take the details of a car, allowing us to get and set the values held. After today’s example you should be able to create your own classes in Xcode and toy around with them.

So far, we have had some great feedback via email, twitter and comments. Itʼs great to see so many people are interested in this subject and itʼs even better to see that so many of you are trying it out for yourself and asking some great questions. Keep it up!

Getting Started

Start by firing up Xcode and creating a new project. Under the Mac OS X separator, click Application, then click Command Line Tool. Finally, change the drop down box to set the type to Foundation.

Xcode New Project

Save the project as whatever you want, I called mine CarApp. Once the project window appears, we need to create a new class. Hit Command-N (or File > New File), navigate to Cocoa Class under Mac OS X and select Objective-C class. Make sure Subclass of is set to NSObject and press Next. Name your class SimpleCar and ensure that a .h file will be created, then save it.

Our class now exists, but it does nothing. Let’s change that by giving it some code. Remember that in Objective-C we split our code into two parts: interface and implementation. It makes logical sense to work on the interface first, so that’s where we’ll start.

Coding the Interface

Open up the SimpleCar.h file and in its current state it should look like this (I’ve omitted the comment header from below)

#import <Cocoa/Cocoa.h>
@interface SimpleCar : NSObject {
}
@end

First of all, we’re including Cocoa.h, which gives us access to such things as NSString, NSMutableString, etc. Then, we create our class (SimpleCar) as a subclass of NSObject.

Now we need to decide on what information our class needs to store. Since we’re using a car as our example we need to store car-related information, such as:

  • Make
  • Model
  • VIN

There’s a lot more we could go into, but for now that will do. For each of these properties, we need to store them in a variable suited for that type of data. Make and model will be a range of characters (such as text, number and possibly punctuation) so it makes sense to use a string. The VIN (Vehicle Identification Number) will only be a number so that’s what we’ll use. Our code now looks like this (header omitted):

@interface SimpleCar : NSObject {
	NSString* make;
	NSString* model;
	NSNumber* vin;
}
@end

We previously said that in order to get or set data from a class, a method should be used. So to set the variables, we need to add methods. To do this, we’ll make four: one will set the make, one the model, one the VIN, and a final method will set both make AND model (just to show you how to use multiple arguments).

@interface SimpleCar : NSObject {
	NSString* make;
	NSString* model;
	NSNumber* vin;
}
// set methods
- (void) setVin:   (NSNumber*)newVin;
- (void) setMake:  (NSString*)newMake;
- (void) setModel: (NSString*)setModel;
// convenience method
- (void) setMake: (NSString*)newMake
        andModel: (NSString*)newModel;
@end

We declare methods after the curly bracket and before @end. By placing a dash (minus sign) before the method, we tell the compiler we’re about to declare an instance method. An instance method is a method executed on our instance. Conversely, a plus sign indicates that the method being invoked is a class method that does not need an individual object instance to execute -more on this later.

Our first method returns void, is called setVin and takes an NSNumber as an argument. Our second method is similar, it returns void, is call setMake, and takes an NSString as an argument. The third is the same, with a different name.

Our final method also returns void but takes two parameters: newMake and newModel, both of which should be NSString. The naming used in this method is similar to how most Objective-C methods are named: in plain English. So when you read the method allowed it’s obvious that the method will “Set make and model.” It’s important to remember that the method name in this case is ‘setMake:andModel:’ – all the argument titles are included in the method name.

An important note is that we use (void) because our methods do not need to return anything. Since all they are doing is setting data and do not need to return anything back (such as a success message) we simply use void.

Next, we will add the methods we will use to get the values. Although we call our methods get and set methods, we only usually use “set” in the title and omit “get.” How you name your methods is ultimately up to you, but dropping “get” is common and helps avoid confusion.

Our new set of methods looks like this:

// set methods
- (void) setVin:   (NSNumber*)newVin;
- (void) setMake:  (NSString*)newMake;
- (void) setModel: (NSString*)newModel;
// convenience method
- (void) setMake: (NSString*)newMake
        andModel: (NSString*)newModel;
// get methods
- (NSString*) make;
- (NSString*) model;
- (NSNumber*) vin;

Notice that the get methods use the same names as the variables in the class. This will make it simple when we fetch the variables. It will be as if we’re accessing the variables directly, essentially making the get methods appear transparent.

Coding the Implementation

So now that the interface is in place and we know what the class will do, we need to implement our methods. Looking back, we have four methods we need to implement: setVin, setMake, setModel and setMake:andModel. Before we move files, copy the method declarations to your clipboard (Cmd+C). Now close SimpleCar.h and fire up SimpleCar.m in the editor, pasting the method declarations in between the @implementation and @end, like so:

@implementation SimpleCar
// set methods
- (void) setVin:   (NSNumber*)newVin;
- (void) setMake:  (NSString*)newMake;
- (void) setModel: (NSString*)newModel;
// convenience method
- (void) setMake: (NSString*)newMake
        andModel: (NSString*)newModel;
// get methods
- (NSString*) make;
- (NSString*) model;
- (NSNumber*) vin;
@end

Obviously this isn’t right, so what we need to do is swap the semi-colons for curly brackets where the inner workings of the method will go, like this:

@implementation SimpleCar
// set methods
- (void) setVin: (NSNumber*)newVin {
}
- (void) setMake: (NSString*)newMake {
}
- (void) setModel: (NSString*)newModel {
}
- (void) setMake: (NSString*)newMake
        andModel: (NSString*)newModel {
}
// get methods
- (NSString*) make {
}
- (NSString*) model {
}
- (NSNumber*) vin {
}
@end

Now we need to give our methods some code. Let’s start with the getter methods as they’re straightforward enough. For each getter method, all we need to do is make sure that the function returns what it is intended to return. For this reason, our getter methods look like this:

- (NSString*) make {
    return make;
}
- (NSString*) model {
    return model;
}
- (NSNumber*) vin {
    return vin;
}

Remember: the methods are returning the variables we defined in the interface file. Don’t get confused between the method names and the variable names.

That’s pretty straightforward, when we call make (for example), then make returns the pointer to an NSString – in this case to the make variable. The same happens for model and vin (except of course vin returns a number).

Now for the setter methods, first we’ll look at the code and then we’ll go through it afterwards. Our setter methods look like this:

// set methods
- (void) setVin: (NSNumber*)newVin {
    [vin release];
    vin = [[NSNumber alloc] init];
    vin = newVin;
}
- (void) setMake: (NSString*)newMake {
    [make release];
    make = [[NSString alloc] initWithString:newMake];
}
- (void) setModel: (NSString*)newModel {
    [model release];
    model = [[NSString alloc] initWithString:newModel];
}
// convenience method
- (void) setMake: (NSString*)newMake
        andModel: (NSString*)newModel {
    // Reuse our methods from earlier
    [self setMake:newMake];
    [self setModel:newModel];
}

The set methods are a bit trickier than our get methods. We want to alloc the values that are passed into each method so that they are owned by the class. We first release these variables in case they are already alloc’d. If they are not alloc’d, then they are nil, and nil objects ignore messages passed to them. We will cover these issues more when we discuss memory management.

Because we actually allocated memory for our objects in the setter methods, we need to be sure we release them when the object is released from memory. To do this, we need to add a custom dealloc method, like so:

-(void) dealloc
{
    [vin release];
    [make release];
    [model release];
    [super dealloc];
}

Testing the Class

Congratulations! If you followed everything above then you should now have a working class (if not, download the source files available with this article). So, let’s test it out.

Open up the main file of your project (mine is called CarApp.m) which by default should look something like this:

#import <Foundation/Foundation.h>
int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
    // Insert custom code here...
    NSLog(@"Hello, World!");
    [pool drain];
    return 0;
}

Delete the comment and NSLog line as we won’t be needing them right now.

In order to begin using our class, we need to pull it into the program. Underneath the original #import line add the following line:

#import "SimpleCar.h"

Our class is now available for use, but we need to create an instance of it in order to test it out. Here’s the code used in total:

#import <Foundation/Foundation.h>
#import "SimpleCar.h"
int main (int argc, const char * argv[]) {
  NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
    SimpleCar *myCar = [[SimpleCar alloc] init];
    NSNumber *newVin = [NSNumber numberWithInt:123];
    [myCar setVin:newVin];
    [myCar setMake:@"Honda" andModel:@"Civic"];
    NSLog(@"The car is: %@ %@", [myCar make], [myCar model]);
    NSLog(@"The vin is: %@", [myCar vin]);
    [myCar release];
  [pool drain];
  return 0;
}

First of all we create a pointer to an instance of SimpleCar called myCar. Next we use alloc and init – these will be discussed later on down the line.

Next, since we need to pass an NSNumber to the setVin method, we make one here. Again we create a pointer to an NSNumber instance called newVin and we initiate it with the integer value of 123. The constant ’123′ is an integer, which is why we use numberWithInt.

Next, we invoke our methods, first of all we put who should receive the message (myCar) and then we use the method setVin. After the colon is the value we are supplying to the method which is the NSNumber we created before. Next we do the same but call the setMake method with two parameters. The reason these parameters are preceded by an @ sign is to tell the compiler that the following is a string.

Finally, we release myCar as we are done with it – more on this later in the series under memory management.

Our class is now working, and in order to see the proof, we added some NSLog statements to print the values to the console. If you open up the console (Run > Console) and then build and run your app, you should see output similar to this:

Debugger

Property and Synthesize

If you look at the code above, a lot of it seems quite pointless and excessive. For example, in our getter methods all we are doing is returning an instance variable – but this takes up three lines of code to do something simple. Also, in our setter methods, we are just setting instance variables – essentially all of our methods, except our method that takes two arguments, seem bloated and in the way. Objective-C solves this with @property and @synthesize, which replace our accessor methods and make for much neater coding.

This is what our new interface file looks like using properties:

#import 
@interface SimpleCar : NSObject {
	NSString* make;
	NSString* model;
	NSNumber* vin;
}
@property(readwrite, retain) NSString* make;
@property(readwrite, retain) NSString* model;
@property(readwrite, retain) NSNumber* vin;
// convenience method
- (void) setMake: (NSString*)newMake
        andModel: (NSString*)newModel;
@end

Wow, that really is a lot shorter. So what’s happening with the @property declarations? First we tell the compiler we are declaring a property by using @property, then we follow with attributes for this property. The attributes are the read/write status of a property and some memory management. We have used readwrite for all, which means getter and setter methods are dynamically created for our instance variables (we could of used writeonly or readonly for just one or the other). The reason we use retain will become clear next time when we cover memory management.

Before this can work, we need to implement it in our implementation file, we do this using @synthesize. Our new implementation file looks like this:

#import "SimpleCar.h"
@implementation SimpleCar
@synthesize make, model, vin;
- (void) setMake: (NSString*)newMake
        andModel: (NSString*)newModel {
    [self setMake:newMake];
    [self setModel:newModel];
}
@end

Doesn’t that look better? Think of it like this, @property replaces all of the interface method declarations for getters and setters, and @synthesize replaces the actual methods themselves. The getters and setters are now dynamically created and we don’t need to waste time creating them unless we need to do something really special.

Wrapping Up

You should now have a firm grip of classes, objects and instances. Sure, you’re not creating classes that will change the world yet, but this stuff takes time. It’s better to learn by example, so if you’re not coding as you go along then be sure to at least download the source files and have a read through (and a compile) to ensure you’re 100% on what’s going on.

Next Time

We’ve mentioned memory management a lot in this tutorial, it’s a very important subject that needs to be addressed (pun intended), so we’ll dive in to that next time. True, it isn’t the most fun subject or the easiest to come to terms with, but it’s absolutely crucial if you want to become a skilled Objective-C programmer.

Challenge

This week’s challenge may be a little tricky, but we’ll see how you get on. First of all, if you haven’t copied all the code above, download the source files that are included with this article. The challenge is to add another class to the project, but this time it should be a subclass of SimpleCar (remember, we define the parent class in the interface file). If you can do that, play around and use the inherited methods and try to add your own for things such as: engine size, doors or height.

Remember: if you have any questions or queries, drop a comment below or shoot me a message on Twitter. The only stupid question is the one you didn’t ask – this series is about learning so feel free to ask away!

Series Navigation«Learn Objective-C: Day 3Learn Objective-C: Day 5»

Note: Want to add some source code? Type <pre><code> before it and </code></pre> after it. Find out more
  • Filip

    When I change the code the use @property and @synthesis my xcode has a warning saying that it may not recognize setvin in the carapp.m file and the project wont run. Any ideas how to fix this?

    • http://www.gorillalogic.com/ Gorilla Logic

      Warning’s will still make your program work but, they will start to make it either run slower or when you enter more code it won’t work anymore and become an error.
      It’s usually a syntax error. I’d have to see the whole code to help.
      Shoot me the code and I will look at it.

      -Thanks

  • Joe Jurca

    Very nice tutorial. One question though.

    When using @property and @synthesize, why doesn’t the implementation file require us to set the vin via a [self setVin:newVin]; statement?

  • A.Arockiaraj

    How can i Compile SimpleCar.m file in Windows for Gnu Step Shell.

  • A.Arockiaraj

    I cant Compile the CarClassTest.m file, i am getting these kind of error

    C:\DOCUME~1\PRODUC~1\LOCALS~1\Temp\ccSxc6EQ.o:CarClassTest.m:(.data+0×8): undefi
    ned reference to `__objc_class_name_SimpleCar’
    collect2: ld returned 1 exit status

    Kindly help me out.

  • Saptarshi

    I’m sorry to say this but the tutorials are quite taugh to understand though I understand the C lanaguage quite well, they are written quite well but they almost always seem to me like a crash tutorial, I’d really appreciate it if you could write this tutorial a little clearly, till the 3rd tutorial it wasn’t a problem but this one’s quite taughto understand.

  • AppDev

    First off, great helpful tutorial! Thanks a lot.

    My question was regarding @ property/@synthesize.

    In the main file we say :
    [myCar setVin:newVin];
    [myCar setMake:@"Honda"];
    [myCar setModel:@"Civic"];

    how does this work? we deleted the setVin/Make/Model functions so what is happening when we say setVin? is this a built in function?

    i dont understand how the one:
    @synthesize make, model, vin;

    line works with the main file.

    Thanks!

  • http://ryanbensonmedia.com Ryan Benson

    For anyone following these tutorials in Xcode 4.3.3, you’ll get a ton of errors because of ARC stuff in the new version. You’ll need to disable ARC and then it’ll work fine.

    Click on you project, in the left hand organizer.
    Select your target, in the next column over.
    Select the Build Settings tab at the top.
    Scroll down to “Objective-C Automatic Reference Counting” (it may be listed as “CLANG_ENABLE_OBJC_ARC” under the User-Defined settings group), (if you do not find ARC option under build settings, you might need to toggle you compiler. You can find it under build settings)
    and set it to NO.
    (Found from: http://stackoverflow.com/questions/6655842/nsautoreleasepool-is-unavailable)

    • Saxjax

      Thanks a lot, this was very helpfull

    • veggiedude

      Maybe things are fixed now. I’m using Xcode 4.6.1 and had no errors.

  • ted

    Thanks! I just written my first Objective-C code! :)
    Your tutorial is easier than other books I have read!

    I did this using Xcode 4.4.1.
    As Ryan mentioned, there is this new ARC thing, but going to menu “Edit -> Refactor -> Convert to Objective-C ARC” fixed the problem without changing any settings.
    It ran perfectly.

    And when creating new class for simpleCar.h, by default it had the #include Foundation instead of Cocoa, which didn’t make any difference for this code.

    Just some feedback:
    I’m sure this is a mistake in your code above:
    #import <cocoa cocoa.h=”"> at the beginning
    and the </cocoa> at the end.

    I think it is good to point out in the interface code, that the gettter and setter (or @property) is after the closing curly bracket }
    Comparing with other languages, usually the { and } covers the whole thing.
    I was confused why it didn’t compile at first because i had everything in the brackets.

  • Kristina

    Hi,
    Thanks for the great tutorial. I understand the code pretty well, but I’m having trouble building it using Xcode 4.4.1. I get the following error:

    Undefined symbols for architecture x86_64:
    “_OBJC_CLASS_$_SimpleCar”, referenced from:
    objc-class-ref in main.o
    ld: symbol(s) not found for architecture x86_64
    clang: error: linker command failed with exit code 1 (use -v to see invocation)

    How can I fix it?

    Thanks!

  • n0n3

    Same problem here, but i’m on windows ;) :
    AppData\Local\Temp\cczzTR0d.o:CarApp.m:(.data+0x38c): unde
    fined reference to `__objc_class_name_SimpleCar’
    collect2: ld returned 1 exit status

  • john f

    I like what I am see here, but like so many I am using 4.4.1 and I have figure most of the errors, but the one I am still getting and cannot figure is the lines:

    [mycar setvin: newvin];
    [mycar setmake: @"Honda" andmodel:@"Civic"];

    and the message for both lines is:

    No visible @ interface for ‘simplecar’ declares the selector ‘setvin’

    I have imported the ‘simplecar.h and in the simplecar.h I have @interface simplecar : NSObject

    Thank you for all the input.
    John

    • Linish

      Hello John,

      I think you might have missed something. I am using XCode 4.2
      Following is the code I used

      main.m
      ———-

      #import
      #import “SimpleCar.h”

      int main (int argc, const char * argv[])
      {

      @autoreleasepool {

      // insert code here…
      //NSLog(@”Hello, World!”);
      SimpleCar *myCar = [[SimpleCar alloc] init];

      NSNumber *newVin = [NSNumber numberWithInt:123];
      NSNumber *newNosDoors = [[NSNumber alloc] initWithInt:4];
      NSNumber *newHeight = [[NSNumber alloc] initWithInt:1000];

      [myCar setVin:newVin];
      [myCar setMake:@"Honda" andModel:@"Civic"];
      [myCar setengineSize:@"12 Valve" andnosDoors:newNosDoors andcarHeight:newHeight];

      NSLog(@”The car is: %@ %@”, [myCar make], [myCar model]);
      NSLog(@”The vin is: %@”, [myCar vin]);
      NSLog(@”The engine size is: %@”, [myCar engineSize]);
      NSLog(@”The car has: %@ door(s)”, [myCar nosDoors]);
      NSLog(@”The height is: %@ mm”, [myCar carHeight]);
      }
      return 0;
      }

      SimpleCar.h
      —————-

      #import
      #import

      @interface SimpleCar : NSObject {
      NSString* make;
      NSString* model;
      NSNumber* vin;
      }

      @property(readwrite, retain) NSString* make;
      @property(readwrite, retain) NSString* model;
      @property(readwrite, retain) NSNumber* vin;

      // Convenience Method
      - (void) setMake:(NSString *)newMake andModel: (NSString*)newModel;

      @end

      SimpleCar.m
      —————-

      #import “SimpleCar.h”

      @implementation SimpleCar

      @synthesize make, model, vin;

      // Convenience Method
      - (void) setMake:(NSString *)newMake andModel:(NSString *)newModel {

      // Reuse our methods from earlier
      [self setMake:newMake];
      [self setModel:newModel];
      }

      @end

      Hope the above code helps

      • Linish

        Missing elements are

        main.m
        ———
        #import <Foundation/Foundation.h>

        simplecar.h
        —————
        #import <Foundation/Foundation.h>
        #import <Cocoa/Cocoa.h>

  • Linish

    Very nice tutorial. Even though it took me a bit time to figure how to add sub class :) for the challenge :)

  • Jesse Muller

    You are not clear enough in this part of the tutorial, to be honest it was actually really bad compared the others.

  • Marco

    Hi,
    Nice tutorial. With help from another post I got the subclass working, but I don’t really understand the logic. Perhaps you can help?

    I made a subclass called subCar, in xCode I see it as a class hanging under SimpleCar. Sounds logical, it’s a subclass after all of SimpleCar.

    Then I would expect all the properties and methods of subCar to be present in an instance of SimpleCar and not the other way around!
    What am I missing here?

    What if there were 2 subclasses of SimpleCar. How would I create 1 instance of all the SimpleCar classes?

    Cheers!!

  • http://www.techstarvation.wordpress.com/ Sumit Gupta

    This is an awesome tutorial. I liked the part where you changed everything to @synthesize and with minor changes everything worked.

  • http://twitter.com/OneSixtyToOne Joe Cesare

    FYI Real VIN numbers are not numeric, they are alpha-numeric.

    • streetjustice

      Agree. And, even if they were 100% numeric (like US ZIP codes) you would never do any mathematical computations with them, so they should be treated as strings. Its a bad example.

      I think its also odd that VIN was chosen, when Make/Model/Year are the top 3 identifiers for a car in any given conversation.

      I stopped reading this article series after this mishap.

    • http://www.facebook.com/priteshdesai Pritesh Desai

      He was just trying to use different types of variables (string as well as numeric).

  • http://www.facebook.com/pankajkhairnar Pankaj Khairnar

    very nice article I just got confuse while using methods created using @synthesize but figured out we can directly use it like [myCar make], [myCar model] and convenience methods still giving me error of passing two values at a time it simply not working for me.

  • Phil Jackson

    Never used a Mac Before, never wrote a piece of objective C or C#. Followed this to the letter and understood clearly. Cheers mate!

  • DaMo

    Thanks for explaining the nuts and bolts of actually writing a program! The Apple documentation explained the concepts and overall organization, but I needed this walk-through to get started writing code.

  • Mohit

    Explain the concept of @property and @synthesize clearly with some example

  • http://www.facebook.com/profile.php?id=100001396315317 Víctor García

    Hi! first of all thanks for share your knowledge;)

    I´m tryng the challenge so i created a subclass of Simplecar called mySimpleCar then in interface file looks like this:

    #import “SimpleCar.h”

    @interface mySimpleCar : SimpleCar
    {
    NSNumber *doors;
    NSString *submodel;
    }
    @property (readwrite, retain) NSNumber *doors;
    @property (readwrite, retain) NSString *submodel;
    -(void) setSubmodel:(NSString *)newsubmodel;
    @end

    The implementation file looks like this:

    #import “mySimpleCar.h”
    @implementation mySimpleCar
    @synthesize submodel, doors;
    -(void)setSubmodel:(NSString *)newsubmodel
    {
    [self setSubmodel:newsubmodel];
    }
    @end

    And the main.m:

    #import
    #import “SimpleCar.h”
    #import “mySimpleCar.h”
    int main(int argc, const char * argv[])
    {
    @autoreleasepool {

    SimpleCar *myCar = [[SimpleCar alloc] init];
    NSNumber *newVin = [NSNumber numberWithInt:123];
    [myCar setVin:newVin];

    [myCar setMake:@"Honda" andModel:@"Civic"];

    mySimpleCar *mynewCar = [[mySimpleCar alloc]init];
    NSNumber *newDoors = [NSNumber numberWithInt:5];
    [mynewCar setDoors:newDoors];

    [mynewCar setSubmodel:@"Passat"];

    NSLog(@” The car is:%@%@”, [myCar make],[myCar model]);
    NSLog(@”The VIN is:%@”, [myCar vin]);
    NSLog(@”My submodel is:%@”,[mynewCar submodel]);
    NSLog(@”The number of doors is:%@”, [mynewCar doors]);
    [myCar release];
    [mynewCar release];
    return 0;
    }
    }
    @end

    I have a bad access in the mySimplecar.m in the line:

    -(void)setSubmodel:(NSString *)newsubmodel
    {
    [self setSubmodel:newsubmodel];
    }

    The warning saids: “writable atomic property sub model cannot pair a synthesized getter with a user defined setter”

    Whats wrong with this method?

    Thanxx!!

    Inde

    • http://www.facebook.com/profile.php?id=100001396315317 Víctor García

      There is no need for -(void)setSubmodel:(NSString *)newsubmodel
      and now works;)

  • Binger

    Property and synthesize part makes no sense for me after all manual…

  • saxjax

    where do we declare

    //reuse methods from earlier
    [self setModel:newModel];
    I may have misunderstood
    but shouldn’t this “setModel “have been declared some where before we can use it as a function, why does it work?

    • sp00n82

      The “setXXX” methods are automatically declared by the @property and @synthesize commands.

      (And as seen in a previous comment, you shouldn’t do both, or it will end in an error message.)

  • KAP

    why do I get an error when I added [vin release] etc.. to Xcode (4.5.2)?

    • sdmeyers

      Because ARC (automatic reference counting) is enabled by default in newer versions of Xcode projects. ARC automatically manages allocating and releasing resources. To turn off ARC, click on CarApp (or whatever you called you project) in the Navigator, then select the CarApp settings under Project. Click the “Build Settings” tab, scroll down and under the “Apple LLVM compiler x.x – Language” settings find Objective-C Automatic Reference Counting and set it to “No”.

      ARC is cool, but it’s actually good to learn without it.

      • ddeloach

        thank you…thank you…these tutorials are great, but comments like these are essential for beginners

      • Jumpin

        THANK YOU!!!!!! :-)

    • sam

      most probably you would be having ‘@autoreleasepool’ being used somewhere

  • KAP

    Why do I get “Incomplete implementation” for @implementation SimpleCar? I am running Xcode 4.5.2.

  • Shadowcub

    I just want to say that I just finished Objective-C for Dummies… and your explanations make a hell of a lot more sense to me coming from Papyrus (and years of modding for the older Elder Scrolls games). That book tends to over-explain everything and there is far too much “or it can be called this or you can do it like this or this or this…” (It’s hard enough learning a new language, I don’t need 12 words for “snow”.) Thank you.

  • Jim

    ***** SPOILERS BELOW ******

    // VerySimpleCar.h

    #import

    #import “SimpleCar.h”

    @interface VerySimpleCar : SimpleCar {

    NSNumber* engineSize;

    NSNumber* doors;

    NSNumber* height;

    }

    @property(readwrite, retain) NSNumber* engineSize;

    @property(readwrite, retain) NSNumber* doors;

    @property(readwrite, retain) NSNumber* height;

    @end

    ————————————————————————————

    // VerySimpleCar.m

    #import “VerySimpleCar.h”

    @implementation VerySimpleCar

    @synthesize engineSize, doors, height;

    @end

    ————————————————————————————

    // main

    #import

    #import “VerySimpleCar.h”

    int main (int argc, const char * argv[]) {

    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    VerySimpleCar *myCar = [[VerySimpleCar alloc] init];

    NSNumber *newEngineSize = [NSNumber numberWithFloat:1.4];

    [myCar setEngineSize:newEngineSize];

    [myCar setMake:@"Seat" andModel:@"Ibiza"];

    NSLog(@”The car is: %@ %@”, [myCar make], [myCar model]);

    NSLog(@”The engine size is: %@”, [myCar engineSize]);

    [myCar release];

    [pool drain];

    return 0;

    }

  • Jon

    So far these tutorials are great. I have a lot of experience programming, but I’ve never touched Objective-C before today. It seems confusing at first, but you do a good job of explaining it.

    I have a question about the custom dealloc method you mention. I originally had that in my implementation. The code compiled fine, but segfaulted every time I ran it. I took the dealloc method out and now it runs without a problem. I noticed that you don’t even have it in your downloadable source. So why mention it at all? Is there a particular instance when it will be necessary to manually deallocate an object in this manner while using an NSAutoreleasePool?

    Thanks

  • http://www.facebook.com/bbumgarner Bill Bumgarner

    This code is wrong in many ways. Every single setter is broken and the general patterns are way out of date.

    DO NOT USE THIS CODE!

    • Daniel Jalkut

      He’s right.

    • Knightrider

      do you have a recommendation for a better site or tutorial? I have relatively basic coding knowledge

  • http://concise-software.blogspot.com/ Alain O’Dea

    Seconded. This code pays no heed to accepted naming conventions for methods and variables Objective C. If you write code like this you will be a burden on your colleagues. It doesn’t matter if code like this works or is easy for non-Objective C to understand. It’s oddball code that will encourage other novices on your team to write more oddball code.

  • Ahmadyar

    Hi every one Plz Tell me the learning of the Objective laungauge which book is the best for learning ?