This page © Philip Regan. All Rights Reserved. All other trademarks copyright their respective owners.
This lexicon compares feature by feature the REALbasic and Objective-C language with Cocoa framework. It is for educational purposes only.
Disclaimer: This page will contain errors and the contents will change without notice. Some features communicate really well this way and others not so much. This has been posted to provide easy access for myself and with the hope that it might help someone else.
| Language Feature | REALbasic | Objective-C |
| Variables |
dim mValue as Integer dim anotherValue as Integer anotherValue = 1 dim mFinalValue as Integer = 2 |
int mValue; int anotherValue; anotherValue = 1 // this would be the preferred method so that we keep giving a default // value of some kind. int mFinalValue = 2;Continuing with Integers using the Number class... NSNumber *newNumber; newNumber = [NSNumber alloc]; [newNumber initWithInt:1]; // ...which can also be handled thusly... NSNumber *newNumber = [[NSNumber alloc] initWithInt:1];Complicated. But wait, it gets better... Placing a * before a variable name will create a ''pointer'' to that value. I think—think—that if a pointer isn't created, then the variable's placement in memory is duplicated and that's a rarity. My understanding at this point is to use the * pretty much all the time. |
| Constants |
Constants scoped to a method are declared in code. The datatype does not need to be declared.
Const mValue = 1 Const mText = "This is a string." Const mFlag = TrueConstants scoped to a class or module are declared in the IDE. There is no text file equivalent. |
To be done |
| Datatypes |
There are a lot of datatypes, but the ones most commonly used are listed here
dim mValue0 as string = "This is a string." dim mValue1 as integer = 42 // Integer breaks out into Signed and Bit count dim mValue2 as Single = 1.0 dim mValue3 as Double = 1.0 dim mValue5 as Boolean = True dim mValue6 as Color = &cC47431 dim mValue7 as Variant = "Any of the above and then some." dim mValue4 as Currency = 5000.00 // this is an incorrect use of this datatype // the remaining datatypes listed are specifically for use in declares |
/* id = a pointer to any type of object BOOL = the same as char but used as a Boolean value YES = 1 NO = 0 IBOutlet = a macro that hints to Interface Builder when it reads the declaration of a class from a .h file IBAction = the same as void and acts as another hint nil = the same as NULL. nil is used instead of NULL for pointers to objects. */ |
| Dummy Row Title |
Dummy Row RB Text
// Dummy Row Code |
Dummy Row ObjC Text
// Dummy Row Code |
| Arrays |
dim mNames(-1) as StringArrays are populated two ways... ...by iteration...
mNames.Append("Tom")
mNames.Append("Dick")
mNames.Append("Harry")
...by the Array command
mNames = Array("Tom", "Dick", "Harry")
|
There are two kinds of arrays: NSArray and NSMutableArray.
NSArray is created with all of the objects that will ever be in it and cannot be altered once created. This is similar to the Pairs object in REALbasic where once it is created, the values cannot be altered. Think of this as a kind of encapsulation technique. Common methods include:
[myArray addObject:[NSNull null]]; |
| Loop Through An Array |
The following is the code standard for going through a For...Next loop, but any of the loops will work here.
dim mNames() as String = Array("Tom", "Dick", "Harry")
dim thisName as integer = 0
dim firstName as integer = 0
dim lastName as integer = Ubound(mNames)
if lastName <> -1 then
for thisName = firstName to lastName
// do something
next
end iF
|
This creates and populates a number array then loops through and outputs the contents of the array.
NSMutableArray *array; // declare the variable, but no array exists yet! This is just a pointer to an instance.
array = [[NSMutableArray alloc] init]; // Create the instance and point the variable to it.
int thisItem = 0;
int firstItem = 0;
int lastItem = 10;
for (thisItem = firstItem; thisItem < lastItem; thisItem++) {
NSNumber *newNumber = [[NSNumber alloc] initWithInt:(thisItem * 3)]; // Create a number object using the NSNumber class
[array addObject:newNumber]; // Add the number object to the array
// The array does not make copies to the objects, it contains pointers to them.
// Copies are very rarely made. (This REALLY is not all that different from RB.)
}
int thisNumber = 0;
int firstNumber = 0;
int lastNumber = [array count];
if (lastNumber > 0) {
for (thisNumber = firstNumber; thisNumber < lastNumber; thisNumber++) {
NSNumber *numberToPrint = [array objectAtIndex:thisNumber];
NSLog(@"The number at index %d is %@", thisNumber, numberToPrint);
}
}
|
| Resize an Array |
Dummy Row RB Text
// Dummy Row Code |
Dummy Row ObjC Text
// Dummy Row Code |
| Math with Numbers |
Dummy Row RB Text
// Dummy Row Code |
Dummy Row ObjC Text
// Dummy Row Code |
| Math Operations with non-Number Datatypes |
Dummy Row RB Text
// Dummy Row Code |
Dummy Row ObjC Text
// Dummy Row Code |
| Boolean Operations |
Dummy Row RB Text
// Dummy Row Code |
Dummy Row ObjC Text
// Dummy Row Code |
| Conditionals |
Dummy Row RB Text
// Dummy Row Code |
Dummy Row ObjC Text
// Dummy Row Code |
| If...Then |
Dummy Row RB Text
// Dummy Row Code |
Dummy Row ObjC Text
// Dummy Row Code |
| If...Else...Then |
Dummy Row RB Text
// Dummy Row Code |
Dummy Row ObjC Text
// Dummy Row Code |
| If...Elseif...Else...Then |
Dummy Row RB Text
// Dummy Row Code |
Dummy Row ObjC Text
// Dummy Row Code |
| Loops |
Dummy Row RB Text
// Dummy Row Code |
Dummy Row ObjC Text
// Dummy Row Code |
| For...Next |
The following is the code standard for going through a loop.
dim mNames() as String = Array("Tom", "Dick", "Harry")
dim thisName as string = 0
dim firstName as string = 0
dim lastName as String = Ubound(mNames)
if lastName <> -1 then
for thisName = firstName to lastName
// do something
next
end if
|
Dummy Row ObjC Text
// Dummy Row Code |
| Do...Loop |
dim mNames() as String = Array("Tom", "Dick", "Harry")
dim thisName as integer = 0
dim firstName as integer = 0
dim lastName as integer = Ubound(mNames)
if lastName <> -1 then
do
// do something
thisName = thisName + 1
loop until thisName > lastName
end if
|
Dummy Row ObjC Text
// Dummy Row Code |
| While...Wend |
dim mNames() as String = Array("Tom", "Dick", "Harry")
dim thisName as integer = 0
dim firstName as integer = 0
dim lastName as integer = Ubound(mNames)
if lastName <> -1 then
while thisName <= lastName
// do something
thisName = thisName + 1
wend
end if
|
Dummy Row ObjC Text
// Dummy Row Code |
| Methods and Functions | ||
| Methods |
Methods are created in the IDE; there is no text file equivalent. The text that is copied from the IDE is shown here
Sub IterateThroughNames()
dim mNames() as String = Array("Tom", "Dick", "Harry")
dim thisName as integer = 0
dim firstName as integer = 0
dim lastName as integer = Ubound(mNames)
if lastName <> -1 then
for thisName = firstName to lastName
// do something
next
end if
End Sub
|
A simple method example from CPFMOX
- (void)increment:(id)sender // public method that returns nothing called increment that takes one argument, sender of type id.
{
count++;
[textField setIntValue:count]; //sends the setIntValue message (calls the method?) to text field.
}
|
| Functions |
Function IterateThroughNames() As String
dim mNames() as String = Array("Tom", "Dick", "Harry")
dim mNamesCombined as string = ""
dim thisName as integer = 0
dim firstName as integer = 0
dim lastName as integer = Ubound(mNames)
if lastName <> -1 then
for thisName = firstName to lastName
dim theName as string = mNames(thisName)
mNamesCombined = mNamesCombined + theName
next
end if
return mNamesCombined
End Function
The function is simply called by the following:
dim mNames as String = IterateThroughNames |
Dummy Row ObjC Text
// Dummy Row Code |
| With Arguments |
Function IterateThroughNames(AllNames as String) As String dim mNames() as String = Split(AllNames, " ") dim mNamesCombined as string = "" dim thisName as integer = 0 dim firstName as integer = 0 dim lastName as integer = Ubound(mNames) if lastName <> -1 then for thisName = firstName to lastName dim theName as string = mNames(thisName) mNamesCombined = mNamesCombined + theName next end if return mNamesCombined End FunctionThe function is simply called by the following:
dim mNamesParsed as String = IterateThroughNames("Tom Dick Harry")
|
Dummy Row ObjC Text
// Dummy Row Code |
| Classes and Class Hierarchy | ||
| Create Class Instance |
Class specifications are created in the IDE; there is no text file equivalent.
There are three ways to create a new instance of a class object in code.
dim mClass as ClassObj mClass = new ClassObj // This has been the preferred method because it "stands out" more. dim mClass as ClassObj = new ClassObj dim mClass as new ClassObj |
Creating a class in Objective-C (taken from CPIOX)
#importCreating the instance (taken from CPIOX) NSMutableArray *foo; // declare the variable foo = [NSMutableArray alloc]; // return a pointer to the space that was allocated for the object. This is actually sending a message to the class. [foo init]; // initialize the object. It actually returns the newly initialized object.Those last two lines are typically combined to the following: NSMutableArray *foo; foo = [[NSMutableArray alloc] init];Constructor in REALbasic is init in Objective-C and can be overridden. Everything is the same as in REALbasic except the init method must return id and the method's code must end with the line return self;. However, if the class is returned in the Constructor method in RB, then RB returns an error.
#import "myClassObj.h"
@implementation myClassObj
- (id)init // note the id being returned.
{
[super init];
// insert code here
return self; // note the self being returned.
}
@end
Sometimes Cocoa classes will return nil when an object could not be initialized. In this case, the following code is used, and is considered best practice in all cases:
#import "myClassObj.h"
@implementation myClassObj
- (id)init
{
if (![super init])
return nil;
// insert code here
return self;
}
@end
To handle init with an argument, it is typical to set a designated initializer that does all the work. All other initializers should call the designated one, and be sure to clearly mark. I think, essentially what's happening here is that init is used to simply call other methods that behave like initializers. So, the basic abstraction runs something like this:
#import "myClassObj.h"
@implementation myClassObj
- (id)init
{
if (![super init])
return nil;
return [self initWithArgument:[NSObject aValue]];
}
- (id)initWithArgument:(NSObject)theArgument // this method must be declared in the header file.
{
if (![super init])
return nil;
// do something with theArgument
return self;
}
@end
In code, the object is initialized like this...
- (id)init
{
[self dealloc]; // we call this so that the memory gets freed up.
@throw [NSException exceptionWithName:@"NAMESPACEPREFIX_BadInitCall" reason:@"Initialize myClassObj with initWithArgument" userInfo:nil];
return nil; // this is why we always check for nil
}
myClassObj *myClassInstance = [[myClassObj alloc] initWithArgument:aValue];Finally, for those inits that absolutely have to have an argument, throw an exception to alert the developer... // CODE TO COMEThe memory has to be managed either manaully or through the auto release pool. This is an entirely separate discussion, but one that is inextricably linked. |
| Inheritance |
Dummy Row RB Text
// Dummy Row Code |
Dummy Row ObjC Text
// Dummy Row Code |
| Input |
Dummy Row RB Text
// Dummy Row Code |
Dummy Row ObjC Text
// Dummy Row Code |
| Keyboard Entry |
Dummy Row RB Text
// Dummy Row Code |
Dummy Row ObjC Text
// Dummy Row Code |
| Open Text File |
dim mFile as Folderitem
dim TIS as TextInputStream
dim mText as String
mFile = GetOpenFolderItem("") // file types can be supplied as an argument.
if mFile <> Nil
if mFile.exists then
TIS = mFile.OpenAsTextFile
if TIS <> nil then
mText = TIS.ReadAll
end if
end if
end If
|
Dummy Row ObjC Text
// Dummy Row Code |
| Output |
Dummy Row RB Text
// Dummy Row Code |
Dummy Row ObjC Text
// Dummy Row Code |
| Save Text File |
Dummy Row RB Text
// Dummy Row Code |
Dummy Row ObjC Text
// Dummy Row Code |
| Graphics |
Dummy Row RB Text
// Dummy Row Code |
Dummy Row ObjC Text
// Dummy Row Code |
| Work With An Interface |
Dummy Row RB Text
// Dummy Row Code |
Dummy Row ObjC Text
// Dummy Row Code |
| Pushbuttons |
Dummy Row RB Text
// Dummy Row Code |
Dummy Row ObjC Text
// Dummy Row Code |
| Pulldown Menus |
Dummy Row RB Text
// Dummy Row Code |
Dummy Row ObjC Text
// Dummy Row Code |
| Scrollbars |
Dummy Row RB Text
// Dummy Row Code |
Dummy Row ObjC Text
// Dummy Row Code |
| Sliders |
Dummy Row RB Text
// Dummy Row Code |
Dummy Row ObjC Text
// Dummy Row Code |
| Events |
Dummy Row RB Text
// Dummy Row Code |
Dummy Row ObjC Text
// Dummy Row Code |
| Open |
Dummy Row RB Text
// Dummy Row Code |
Dummy Row ObjC Text
// Dummy Row Code |
| Mouse Actions |
Dummy Row RB Text
// Dummy Row Code |
Dummy Row ObjC Text
// Dummy Row Code |
| Dummy Row Title |
Dummy Row RB Text
// Dummy Row Code |
Dummy Row ObjC Text
// Dummy Row Code |
NSAssert(theDate == nil, @"Argument must be non-nil.");