Overview

Short Introduction to iOS for Java Developers: Objective-C

9 Comments

For Java developers starting iOS development, the hardest shift will probably be the Objective-C, the Apple’s language of choice. The Objective-C is extension of the standard ANSI C language, providing syntax for defining classes and methods, and other object oriented constructs. So any experience with C will help you a lot. In fact, since Objective-C is a superset of the ANSI version of the C, you’ll need to know the basics of C before learning Objective-C.

Unlike in Java, where you define and implement class in one file, in Objective-C you have two files. Same as in C, you have header files (.h) for public declarations and source files (.m) for implementation, which can hold both Objective-C and C code. You can even use C++ if you want (.mm files). The following example shows DeathStar class implemented in Java and Objective-C.

DeathStar.java

import com.empire.Jedi;
import com.empire.SpaceShip;
import com.empire.SuperWeapon;
 
public class DeathStar extends SpaceShip implements SuperWeapon {
 
	private boolean complete;
	private Integer power;
 
	public boolean isComplete() {
		return complete;
	}
 
	public void setComplete(boolean complete) {
		this.complete = complete;
	}
 
	public Integer getPower() {
		return power;
	}
 
	public void setPower(Integer power) {
		this.power = power;
	}
 
	public static void turnToDarkSide(Jedi jedi) {
		//...
	}
 
	public void destroyPlanet() {
		//...
	}
 
	@Override
	public void lockTargetAt(int xCoord, int yCoord) {
		//...
	}
 
	@Override
	public boolean fire() {
		// ...
		return true;
	}
}

In Objective-C it would look like this:

DeathStar.h

#import "SpaceShip.h"
#import "SuperWeapon.h"
#import "Jedi.h"
 
 
@interface DeathStar : SpaceShip <SuperWeapon> {
	BOOL completed;
	NSNumber *power;
}
 
@property(nonatomic, assign) BOOL completed;
@property(nonatomic, retain) NSNumber *power;
 
+ (void)turnToDarkSide:(Jedi *)jedi;
- (void)destroyPlanet;
 
@end

DeathStar.m

#import "DeathStar.h"
 
 
@implementation DeathStar
 
@synthesize completed;
@synthesize power;
 
 
-(void)dealloc {
	[power release], power = nil;
	[super dealloc];
}
 
- (void)destroyPlanet {
	//...
}
 
+ (void)turnToDarkSide:(Jedi *)jedi {
	//...
}
 
 
#pragma mark -
#pragma mark SuperWeapon
 
- (void)lockTargetAtX:(NSInteger)xCoord andY:(NSInteger)yCoord {
	//...
}
 
- (BOOL)fire {
	//...
	return YES;
}
 
@end

Protocols

In the example we can see that DeathStar class extends SpaceShip and conforms to the SuperWeapon protocol. A protocol declares methods that can be implemented by a class. They simply define an interface that other objects are responsible for implementing. When a class implements methods of a protocol we say that the class conforms to that protocol. Protocols can have optional and required methods. The Objective-C protocols are something similar to Java interfaces. In fact, it’s said that Java interfaces where inspired by protocols. Protocols are used frequently to specify the interface for delegate objects. Delegate pattern is massively used in iOS development, so you should get familiar with it. Here is the declaration of the SuperWeapon protocol:

SuperWeapon.h

@protocol SuperWeapon
 
- (void)lockTargetAtX:(NSInteger)xCoord andY:(NSInteger)yCoord;
- (BOOL)fire;
 
@end

And here is the Java counterpart:

SuperWeapon.java

package com.empire;
 
public interface SuperWeapon {
	void lockTargetAt(int xCoord, int yCoord);
	boolean fire();
}

Properties

Objective-C supports both strong and weak typing. For example:

NSNumber *power; // strong typing
id       power; // weak typing

In Objective-C object references are pointers. You have to remember to put the * in front of the variable names for strongly-typed object declarations. The id type implies a pointer. So this is quite different from Java, but if you have some experience with C, you should be familiar with this.

Declared properties are a convenience notation used to replace the declaration and, optionally, implementation of accessor methods. This is something extensively used, and very much recommended. This will also help you with the memory management, which will talk about later.

@property(nonatomic, retain) NSNumber *power;

Properties are declared with @property directive, followed by and optional options, followed by a type and name. In your class implementation, you can use the @synthesize compiler directive to ask the compiler to generate the accessor methods according to the specification in the declaration.

 @synthesize power;

The given attributes in the example specifies that retain should be invoked on the object upon assignment (we’ll talk more about this in memory management) and that property is nonatomic. By default properties are atomic so that synthesized accessors provide robust access to properties in a multithreaded environment (Remember, Objective-C is used also for Mac OS X development).

Those two lines of code in Java would look like this:

	private Integer power;
 
	public Integer getPower() {
		return power;
	}
 
	public void setPower(Integer power) {
		this.power = power;
	}

More about properties and declaration attributes you can read here.

Methods and Messaging

A class in Objective-C can declare two types of methods: instance methods and class methods, marked by -/+:

+ (void)turnToDarkSide:(Jedi *)jedi;
- (void)destroyPlanet;

Class methods are like static methods in Java. You call a method by messaging an object. A message is a method signature with the parameters. Messages are dispatched dynamically. Messages are enclosed by brackets, with the object receiving the message on the left side and the message (along with any parameters required by the message) on the right.

[self destroyPlanet];
[DeathStar turnToDarkSide:jedi];

In Java this would look like:

this.destroyPlanet();
DeathStar.turnToDarkSide(jedi);

That’s another big syntax difference from Java. The exception are accessor methods which use standard dot syntax:

self.power = 60;

In Java:

this.setPower(60);

You can also target a method by using selectors which can be useful when handling events. Selectors are like pointers to a method. This is something that Java does not have.

[[UIBarButtonItem alloc] initWithImage:image
                         style: UIBarButtonItemStylePlain 
                         target:self
                         action:@selector(destroyPlanet)];

The Memory Management

While there is a Garbage Collector that you can use for OS X application, for iOS you must manage your memory manually. This is probably the most difficult thing to get used to for Java developers. You should try to ensure that your application does not use more memory than necessary, since memory is usually scarse resource in mobile devices. Objects should be destroyed when they are no longer needed, but it is also important that you do not destroy objects that are still used. Cocoa defines a mechanism by which you can specify when you need an object and when you have finished with it. It’s called object ownership.

Any object may have one or more owner. As long as an object has at least one owner, it continues to exist. If an object has no owners, the runtime system destroys it automatically. You only release or autorelease objects you own.

  • You own any object you create (alloc, copy, new)
  • You can take ownership of an object using retain
  • You must relinquish ownership of objects you own when you’re finished with them (release)
  • You must not relinquish ownership of an object you do not own

Tip: Class methods by convention own the returning objects, so you do not release them.

The ownership policy is implemented through reference counting or “retain count”. Each object has a retain count.

  • When you create an object, it has a retain count of 1.
  • When you send an object a retain message, its retain count is incremented by 1.
  • When you send an object a release message, its retain count is decremented by 1.
  • When you send an object a autorelease message, its retain count is decremented by 1 at some stage in the future
  • If an object’s retain count is reduced to 0, it is deallocated

Tip: Use properties, they simplify the memory management.

While in Java you create an object and can forget about it (leaving it to Garbage Collector):

Jedi jedi = new Jedi();

in Objectiv-C you have to allocate memory for it, initialize it, and destroy it after you’ve finished with it:

Jedi *jedi = [[Jedi alloc] init]; // create the Jedi
[DeathStar turnToDarkSide:jedi]; // turn Jedi to the dark side
[jedi release], jedi = nil; // destroy the Jedi

More about memory management you can read here:

You can find short introduction to Objective-C here.
More detailed overview of Objective-C can be found here.

Previous: SDK | Next: MVC

Kommentare

  • Tobias Trelle

    April 19, 2011 von Tobias Trelle

    I really like the concise way of property handling in Objective-C. Would be great to have something like that in Java.

  • April 21, 2011 von Rich

    A very nice intro. Some aspects of Objective-C I didn’t quite “get” before became clear for me.

  • very wel compared.. objective-c with java….

  • January 26, 2012 von MunyaC

    This is quite a good explanation. I’m a java developer and the first time I developed in objective-c I never saw all these similarities. Nice Post!

  • what an explanation

  • nice and concise. thanks!

  • August 7, 2014 von Anthony Robledo

    Great, great, great, great article.

  • This post was written before the ARC came out. For memory management I recommend using ARC, it takes much of the pain away, and it’s pretty much standard today. Or switch to Swift 😉

  • February 22, 2015 von Craig K

    In your Java example, right at the beginning, I think you’re missing a line.

    @ThatsNoMoon

Comment

Your email address will not be published. Required fields are marked *