Skip to main content

Posts

Breaking Retain Cycles with @Weak and Other Techniques

The runtime on iOS and macOS uses reference counting to manage memory. When two objects make strong references to each other, a retain cycle is formed. Consider a Document object that has a Header. The Document owns the Header, but often the Header is also modeled to have a document (or “parent”) field:

classDocument{privatefinal Header header =new Header(this);}classHeader{privatefinal Document document; Header(Document document){this.document= document;}}
If nothing breaks one of those two strong references (such as by setting one of them to null), a retain cycle is formed, and both objects will never be deallocated in a reference-counting system even after all outside references to any of them are gone. They therefore leak memory.
Retain cycles are something Objective-C and Swift programmers have to think about regularly. They are usually not of concern to Java programmers thanks to garbage collection, but when your Java program gets translated to Objective-C, you need to make sur…
Recent posts

Default Methods

We are pleased to announce the support for Java 8 default methods in J2ObjC. The compiler also translates static methods in interfaces now. Together they make Java interfaces more useful, and, when combined with lambdas, enable a wide range of new idioms and programming styles. To translate this new language feature, pass the command line argument -source 8 to j2objc.

The Java Tutorials has a good introduction to default and static methods in interfaces. Another good introduction is Richard Warburton's Java 8 Lambdas. Here we give three short examples to show why this language feature is useful.
Providing New Features that Build Upon Essential Methods Default methods enable us to keep the requirements of an interface minimal while still providing good default implementations that build upon those essential methods. Imagine you have an interface for objects (for example, appliances) whose date and time can be set:

interfaceDateTimeSettable{voidsetDate(int year,int month,int day);void…

Lambdas in Java 8 - (Dys)functional Interfaces

1970 - Guy Steele and Gerald Sussman create Scheme. Their work leads to a series of "Lambda the Ultimate" papers culminating in "Lambda the Ultimate Kitchen Utensil." This paper becomes the basis for a long running, but ultimately unsuccessful run of late night infomercials. Lambdas are relegated to relative obscurity until Java makes them popular by not having them.
James Iry A Brief, Incomplete, and Mostly Wrong History of Programming Languages

So we finally have lambda expressions in Java with Java 8. Well, actually we have had them for a year now, and companies and universities have started upgrading at a snail’s pace. Some from Java 6 to Java 7, but let’s ignore that for now and instead talk about lambdas, implementation details, and how this all impacts j2objc and you.

Before we talk about lambdas we have to talk about functional interfaces, and after we talk about functional interfaces we will need to mitigate confusion with history, with a short lambda ances…

Protocol Buffers!

Protocol Buffers are Google’s preferred method of representing and communicating structured data. For most Google projects, protocol buffers are used for data storage or client-server communication. As such, a working protocol buffer solution has been a requirement for J2ObjC from day one. Until recently our solution contained internal dependencies that prevented it’s public release, but now I am very pleased to be able to make our internal solution available to all J2ObjC users.

Let’s take a quick look at how protocol buffers are used (for a more in-depth look you can read through the Protocol Buffers Developer Guide). Suppose my app needs a geographic location, so I would create a geo.proto file with the following declaration:
message Location {
  optional string name = 1;
  optional double latitude = 2;
  optional double longitude = 3;
}
Then I can use the protocol buffer compiler, “protoc”, to generate data types in the languages I need:
$ protoc --java_out=src/java --cpp_out=src/cpp ge…

Android and iPhones and Web, oh my

It's regularly asked why J2ObjC purposely avoids translating UI code; after all, wouldn't it be wonderful if a tool existed where a developer can drop in Android source and out pops an iOS app? Our usual response is that world-class apps need user interfaces that are tightly integrated with each platform, and that common-denominator attempts to span platforms provide degrades user experiences. As I found when working on Swing many years ago, customers notice the smallest deviations from a platform's UI standards and generally find them off-putting. But non-compromising UIs are just one of the reasons we focus on translating shared logic.

The pressure for platform-independent apps is due to the cost and effort to create separate versions for each platform. This is especially true for the non-UI parts of the app, where the logic is identical but must be rewritten in different languages for Android, iOS, and browsers. Software development is expensive, and this sort of redund…

cfront: a J2ObjC Inspiration

Developers new to J2ObjC may find its "Java compiles to Objective-C, which compiles to .o files" approach a little strange, but it's based on precedent: cfront. When C++ was first released, no compilers translated C++ sources directly into object files. Instead, the cfront script translated C++ into temporary C files, and then invoked cc to compile them. cfront took similar options as cc, so most C++ developers used it as if it was a true C++ compiler. The cfront script wrapped around a transpiler, though; it was a script very similar to combining the j2objc and j2objcc scripts in J2ObjC.
One of cfront's innovations was name mangling, where C++ type information was embedded into C names. J2ObjC also uses name mangling (described here) to support features like packages and Java's method overloading semantics that Objective-C doesn't directly support. For example, the JRE has both java.util.Date and java.sql.Date classes; since C names are all global in scope,…