Pages

Wednesday, December 30, 2009

Objective-C. NSArray, NSMutableArray

It's a collection of objects.
#import <Foundation/NSObject.h>
#import <Foundation/NSArray.h>
#import <Foundation/NSstring.h>
#import <Foundation/NSAutoreleasePool.h>


int main (int argc, const char * argv[])
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

NSArray *months = [NSArray arrayWithObjects:
@"January", @"February",
@"March", @"April", @"May",
@"June", @"July", @"August",
@"September", @"October", @"November",
@"December", nil];

NSLog(@"Month Name");
NSLog(@"-------------");

int i;
for (i = 0; i < [months count]; ++i)
{
NSLog(@"%2i. %@", i + 1, [months objectAtIndex: i]);
}

[pool drain];
return 0;
}



There is also a mutable version of the array: NSMutableArray. The following program generates the prime numbers and store them in the array (because the number of the elements in the array is unknown in the beginning, NSMutableArray is used):
#import <Foundation/NSObject.h>
#import <Foundation/NSArray.h>
#import <Foundation/NSString.h>
#import <Foundation/NSAutoreleasePool.h>
#import <Foundation/NSValue.h>

#define MAX_PRIME 50

int main (int argc, const char * argv[])
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

NSMutableArray* primes = [NSMutableArray arrayWithCapacity: 20];

[primes addObject: [NSNumber numberWithInteger: 2]];
[primes addObject: [NSNumber numberWithInteger: 3]];

BOOL isPrime;
int p, i, prevPrime;
for (p = 5; p < MAX_PRIME; p += 2)
{
isPrime = YES;
i = 1;
do {
prevPrime = [[primes objectAtIndex: i] integerValue];
if ( p % prevPrime == 0)
isPrime = NO;

++i;
} while (isPrime == YES && p / prevPrime >= prevPrime);

if (isPrime)
[primes addObject: [NSNumber numberWithInteger: p]];
}

for (i = 0; i < [primes count]; ++i)
NSLog(@"%li", (long)[[primes objectAtIndex: i] integerValue]);


[pool drain];
return 0;
}

Objective-C. NSNumber

The numeric data types in Objective-C can be objects. So we can send a message to them (sounds strange for someone who began programming from C). One more strange reason to have the numbers as the objects is a possibility to store them in NSArray (trivial malloc works in Objective-C, so why I need an array of objects to save the integer values?).

Anyway, even if I do not understand, it exists:
#import <Foundation/NSObject.h>
#import <Foundation/NSAutoreleasePool.h>
#import <Foundation/NSValue.h>

int main (int argc, const char * argv[])
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

NSNumber* number;

number = [NSNumber numberWithInteger:112];
NSLog(@"integer %@", number);

number = [NSNumber numberWithFloat:123.45];
NSLog(@"float %@", number);

[pool drain];
return 0;
}

Objective-C. Program not from the book

First time something that was not in the book:



#import <Foundation/Foundation.h>

@interface Dot: NSObject
{
int x;
int y;
}

@property int x, y;

@end;

@implementation Dot

@synthesize x, y;

@end

@interface Something : NSObject
{
int capacity;
Dot** array;
}

@property int capacity;
@property (nonatomic, assign) Dot** array;

- (Something*) init;
- (Something*) initWithCapacity : (int)n;
- (BOOL) isEmpty;
- (void) dealloc;

@end

@implementation Something

@synthesize array;
@synthesize capacity;

- (Something*) init
{
array = Nil;
capacity = 0;
return self;
}

-(Something*) initWithCapacity : (int)n
{
int i;
self = [super init];
array = (Dot**)malloc(n * sizeof(Dot*));
for (i = 0; i < n; ++i)
{
array[i] = [[Dot alloc] init];
array[i].x = i;
array[i].y = i * i;
}
capacity = n;
return self;
}

- (BOOL)isEmpty
{
return capacity == 0;
}

- (void) dealloc
{
int i;
for (i = 0; i < capacity; ++i)
{
[array[i] release];
}
free(array);
[super dealloc];
}

@end


int main (int argc, const char * argv[])
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

Something* something = [[Something alloc] initWithCapacity: 10];

int i;
for (i = 0; i < something.capacity; ++i)
{
NSLog(@"array[%i] = %i, %i", i, something.array[i].x, something.array[i].y);
}

[something release];

Something* test = [[Something alloc] init];
if (![test isEmpty])
test.array[0].x = 1;
[test release];
[pool drain];
return 0;
}


Tuesday, December 29, 2009

Objective-C. Pointers to Functions

Each day I see more and more nice and well-known C-things working in Objective-C.
Here is a program demonstrating how to work with the pointer to a function in Objective-C:

#import <Foundation/Foundation.h>

void hello(char str[])
{
NSLog(@"%s", str);
}

int main (int argc, const char * argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

char word[] = { 'H', 'e', 'l', 'l', 'o', '\0' };
hello(word);

const char* say = "hello, world!";
hello(say);

void (*fnHello)(char[]);
fnHello = hello;
fnHello("bye");

[pool drain];
return 0;
}

The screenshot:


Monday, December 28, 2009

Objective-C. Array.

Objective-C is still C language. And seems like all about the common C arrays works in Objective-C. Here is a small program that generates a table of Fibonacci numbers:
#import <Foundation/Foundation.h>

#define ARRAY_SIZE 15

int main (int argc, const char * argv[])
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

int Fibonacci[ARRAY_SIZE], i;
Fibonacci[0] = 0; //by definition
Fibonacci[1] = 1;

for (i = 2; i < ARRAY_SIZE; ++i)
{
Fibonacci[i] = Fibonacci[i - 2] + Fibonacci[i - 1];
}

for (i = 0; i < ARRAY_SIZE; ++i)
{
NSLog(@"[%i] = %i", i, Fibonacci[i]);
}
[pool drain];
return 0;
}



The char array is the same char array:
#import <Foundation/Foundation.h>

int main (int argc, const char * argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

char word[] = { 'H', 'e', 'l', 'l', 'o', '\0' };
NSLog(@"%s", word);
[pool drain];
return 0;
}

As you see the size of the array is not mentioned in the array declaration. The array is initialized and, because, I'm going to print it in the console, I set the last array element as 0.


Objective-C. Categories

It is an absolutely new for me. I've never seen such thing in C, C++ or C#. I even do not know if it is good or bad. From other side, I do not understand why it is not implemented in other C++ compilers.

It's named as Categories. Shortly if you already have a class declared in a header file, let's say in file myclass.h, and the class implementation is in myclass.cpp file, you may add new methods to this class declared and implemented in other files. It is possible to new methods even for the classes from the Foundation framework.

I added methods to the class Fraction I used in my previous posts. Here is MathOp.h file:
#import "Fraction.h"

@interface Fraction (MathOp)
-(void) add: (Fraction*) fraction;
-(void) substruct: (Fraction*) fraction;

@end
And here is MathOp.m:
#import "MathOp.h"


@implementation Fraction (MathOp)

-(void)add: (Fraction*) fraction
{
numerator = numerator * fraction.denominator + fraction.numerator * denominator;
denominator = denominator * fraction.denominator;
[self reduce];
}

-(void) substruct: (Fraction*) fraction
{
numerator = numerator * fraction.denominator - fraction.numerator * denominator;
denominator = denominator * fraction.denominator;
}

@end
This is a program written to test this class:
#import <Foundation/Foundation.h>
#import "Fraction.h"
#import "MathOp.h"

int main (int argc, const char * argv[])
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

Fraction *fraction1 = [[Fraction alloc] initWith: 1 : 2];
Fraction *fraction2 = [[Fraction alloc] initWith: 1 : 3];

[fraction1 substruct: fraction2];
[fraction1 print];

[fraction1 release];
[fraction2 release];
[pool drain];
return 0;
}
And it works fine:



It is impossible to add an instance variable, but this way allows to add new methods and override the existing ones. In the last case, there is no access to the original method. It is applied to all classes derived from the modifying one.

You may have as many categories as you wish. The name of the category must be unique. If a method is defined in more than one category, the language does not specify which one will be used.

Sunday, December 27, 2009

Objective-C. Exception Handling Using @try

For me it is a bit strange that Xcode compiles this code:
#import <Foundation/Foundation.h>

@interface Test: NSObject
{
int x;
}

@property int x;
-(void) print;

@end

@implementation Test

@synthesize x;

-(void) print
{
NSLog(@"x = %i", x);
}

@end


int main (int argc, const char * argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

Test* test = [[Test alloc] init];
test.x = 10;
[test print];

[test noSuchMethod];

[test release];
[pool drain];
return 0;
}
As you see I call noSuchMethod from the test object. Xcode shows just a warning:


Of course, the application crashes:


The book recommends to use @try in such cases:
@try {
[test noSuchMethod];
}
@catch (NSException *exception) {
NSLog(@"Caught %@%@", [exception name], [exception reason]);
}

And so here is the console:


@finally block also can be used and works exactly as in any C++ compiler. Same is right about @throw directive.

Software Rendering School

On DevMaster.net I found a series of tutorials: Software Rendering School.

I’ve read first two parts – it is really amazing, everything is explained is a very simple language and does not require to remember the University mathematics.

Few nice things from the beginning:

  • You may find an explanation what is the difference between the points and vertices – the points are simply random positions set by their coordinates, and vertices may have more data bound to them, vertices are positions bound to primitives like triangle.
  • The basic operations you can perform with the points are translation, scaling and rotation.
  • Translation is a simple movement:

new.x = point.x + translate.x;

new.y = point.y + translate.y;

new.z = point.z + translate.z

  • The scaling is also a kind of a movement, but we multiply the coordinates:

new.x = point.x * scale.x;

new.y = point.y * scale.y;

new.z = point.z * scale.z;

  • The most complex operation is the rotation:

//X-Rotation

new.x = v.x

new.y = v.y * cos(a) – v.z * sin(a)

new.z = v.y * sin(a) + v.z * cos(a)

//Y-Rotation

new.x = v.x * cos(a) – v.z * sin(a)

new.y = v.y

new.z = v.x * sin(a) + v.z * cos(a)

//Z-Rotation

new.x = v.x * cos(a) – v.y * sin(a)

new.y = v.y * sin(a) + v.x * cos(a)

new.z = v.z

  • Vector, in the simplest way, can be described by its position, direction and magnitude.
  • Dot product is cos of the angle between two vectors:

dot  = v1.x * v2.x + v1.y + v2.y + v1.z * v2.z

dot = cos(a)

More about Dot Product: http://mathworld.wolfram.com/DotProduct.html

  • Cross product of two vectors is another vector, which is perpendicular to both source vectors:

new.x = v1.y * v2.z – v2.z – v1.z

new.y = v2.x * v1.z – v1.x * v2.z

new.z = v1.x * v2.y – v2.x * v2.y

More about Cross Product: http://mathworld.wolfram.com/CrossProduct.html

And here is a joke about the subject:

Question: What do you get if you will cross an elephant and a grape?

Answer: elephant grape sine-of-theta

  •  Matrix is an object with a given number of rows and columns.
  • Parallel projection:

x2 = x1 + viewportWidth / 2

y2 = –y1 + viewportHeight / 2

z2 = 0

  • Perspective projection is clear when you know that

y2 / y1 = z2 / z1 = d / z

or

x2 / x1 = z2 / z1 = d / z

where d is the distance to the projection plane.

 

 

 

    Saturday, December 26, 2009

    Objective-C. 0 + 1/2 + 1/4 + 1/8 + 1/16 +...




    Google knows too much. Actually, I was surprised to find out that I can check my math exercise without a calculator or another application. I have to learn Objective-C and now I do not see another way but make simple math exercises.

    Here is a program calculating the same formula - sum of fractions 1/2, 1/4, 1/8, etc. The denominator is always 2 in power of n. If the n is big enough the result, the sum of this series should approach 1.

    #import <Foundation/Foundation.h>
    #import "Fraction.h"

    int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    Fraction *fraction = [[Fraction alloc] init];
    Fraction *sum = [[Fraction alloc] init];
    int n, i, pow2;

    [sum setTo: 0 over: 1];

    NSLog(@"Enter your value for n:");
    scanf("%i", &n);

    pow2 = 2;
    for (i = 1; i <= n; ++i)
    {
    [fraction setTo: 1 over: pow2];
    [sum add: fraction];
    pow2 *= 2;
    }

    NSLog(@"After %i iteration, the sum is %g", n, [sum convertToNum]);

    [fraction release];
    [sum release];
    [pool drain];
    return 0;
    }

    And here is the console:


    This program uses the class Fraction declared in file Fraction.h:

    #import <Foundation/Foundation.h>


    @interface Fraction : NSObject {
    int numerator;
    int denominator;
    }

    @property int numerator, denominator;

    -(void) print;
    -(double) convertToNum;
    -(void) setTo: (int)n over: (int)d;
    -(void) add: (Fraction*) fraction;
    -(void) reduce;

    @end

    and the class is implemented in Fraction.m:

    #import "Fraction.h"

    @implementation Fraction

    @synthesize numerator, denominator;

    -(void)print
    {
    NSLog(@"%i/%i", numerator, denominator);
    }

    -(double)convertToNum
    {
    if (denominator != 0)
    return (double) numerator / denominator;
    return 1.0;
    }

    -(void) setTo: (int) n over: (int) d
    {
    numerator = n;
    denominator = d;
    }

    -(void)add: (Fraction*) fraction
    {
    numerator = numerator * fraction.denominator + fraction.numerator * denominator;
    denominator = denominator * fraction.denominator;
    [self reduce];
    }

    -(void) reduce
    {
    int u = numerator;
    int v = denominator;
    int temp;

    while (v != 0)
    {
    temp = u % v;
    u = v;
    v = temp;
    }

    numerator /= u;
    denominator /= u;
    }


    @end

    Thursday, December 24, 2009

    Objective-C. Prime Numbers

    This program generates a table of prime numbers:
    #import <Foundation/Foundation.h>

    int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];


    int p, d;
    BOOL isPrime;

    for (p = 2; p <= 50; ++p)
    {
    isPrime = YES;

    for (d = 2; d < p; ++d)
    {
    if (p % d == 0)
    isPrime = NO;
    }

    if (isPrime)
    NSLog(@"%i ", p);
    }

    [pool drain];
    return 0;
    }



    Monday, December 21, 2009

    Стив Джопс - Лучший CEO года

    Имя и фамилия (уж очень экзотична для русского уха) знакомы еще по-школьному курсу информатики. Этот человек еще лет 30 назад попал в историю со своим первым "гаражным" компьютером. Имя его коллеги уже и забыли (Стефан Возняк).

    Harvard Business Review:
    The Best-Performing CEOs in the World

    С 1997 года руководит компанией Apple и прошлом году увеличил ее рыночную стоимость до 160 миллиардов.

    Его тезке (или, пожалуй, антипод) Стиву Балмеру, по слухам, грозит увольнение:
    Steve Ballmer, CEO of Microsoft, to be fired in 2010 due to bad performance of Windows Mobile!

    Три успешных года с iPhone для Apple. Три года сплошных неудач для Microsoft с Windows Mobile.

    Sunday, December 20, 2009

    Прогноз на 2010 гол для Microsoft

    MS Mobile (такое промайкрософтовское название) выдал статью:
    Windows Phone predictions for 2010 - what will happen with Windows Mobile in 2010
    Почитайте. Посмотрите, как безнадежно пессимистическое настроение прячут под сарказмом.
    В этом году Microsoft потерял много сторонников. И раздавали MVP очень широко. Да что-то не помогло.
    Мой сарказм уже прошел - вот Objective-C изучаю. Даже этот пост на MAC печатаю - кто бы подумать? Я и сам бы не поверил в прошлом году. Помнится, я очень удивился, когда увидел в центральном офисе Microsoft в Редмонте руководителя группы Windows CE с iPhone в руках.

    46% японского рынка уже принадлежит iPhone

    Япония, этот всемирно признанный технологический лидер, выбрала iPhone: Apple Insider. Я то думал, что для них такой телефон никакая не новинка, что они уж лет пять как наручнами видеофонами пользуются.
    Может все и проще - цена для них вполне приемлема, вот и все.
    А, вообще, говорят, что уже продано 78 миллионов телефонов iPhone и iPod:
    Where in the world are Apple's 78 million handsets?

    Saturday, December 19, 2009

    Objective-C. Simplest Data Types

    I just made a simple application: New Project from the File menu -> Command Line Utility -> Foundation Tool. Then put the following code:
    #import <Foundation/Foundation.h>

    int main (int argc, const char * argv[])
    {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    int intVar = 100;
    long int longIntVar = 131071100L;
    float floatVar = 331.79;
    double doubleVar = 8.44e+11;
    long double longDoubleVar = 1.234e+7L;
    char charVar = 'W';

    NSLog(@"intVar = %i", intVar);
    NSLog(@"longIntVar = %li", longIntVar);
    NSLog(@"floafVar = %f", floatVar);
    NSLog(@"doubleVar = %e", doubleVar);
    NSLog(@"longDoubleVar = %Le", longDoubleVar);
    NSLog(@"doubleVar = %g", doubleVar);
    NSLog(@"charVar = %c", charVar);

    [pool drain];
    return 0;
    }

    Then launch the console and press Build & Go:


    There is one special type in Objective-C. This is id. This type is used to store objects of any type. I think it is something like void*. So it is possible to write the following code:
    id everything = (id)intVar;
    NSLog(@"variable of id type = %i", everything);

    Flock. Blog Writer.

    Till now everything looks nice.

    Blogged with the Flock Browser

    Friday, December 18, 2009

    Microsoft DIA SDK

    Microsoft Debug Interface Access SDK. I've never heard about it and found it just today when was reading this article: A Simple Profiler using the Visual Studio C/C++ Compiler and DIA SDK
    The SDK name explains everything.

    Begin with Objective-C

    My friend presented me a book: Stephen G. Kochan. "Programming in Objective-C 2.0". So I'm with this book now. After first 15 pages I cannot recommend it or not, but I can say that the Objective-C reality is not scared me anymore, I even like Xcode.
    It is unbelievably easy to to make the simplest "Hello, World!" application:
    1. In Xcode select New Project in the File menu.
    2. In the wizard (or what is the name of this window in Xcode), in the left panel select Command Line Utility.
    3. In the right panel select Foundation Tool.
    4. Press Choose button in the right-down corner.
    5. Type the project name and save the project.
    Done.
    There is only one file with .m extension - click on it and see the code:
    #import <Foundation/Foundation.h>

    int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    // insert code here...
    NSLog(@"Hello, World!");
    [pool drain];
    return 0;
    }
    Is it C?
    int main, and return in the end are written in C. All other lines? Maybe, the line with NSLog is in C. #import instead of #include, theses lines with the brackets about a pool...

    In order to see how this application works, you need to launch the console - it is in the Run menu (or shift+cmd+R). In the console press Build and Go button and see "Hello, World!" text.
    The book proposed to modify the text - "Programming is fun!". I did:

    I found the application in Finder and launched it:


    Let's delete these two lines with the pool,  if we do not understand what is this. Then launch Console from the Run menu and press Build & Go button there - the application still works.

    Let's move forward. Next exercise is just from the school - calculate 2 + 2:


    Here is the code:
    #import <Foundation/Foundation.h>

    int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
    int sum;

    sum = 2 + 2;
    NSLog(@"2 + 2 = %i", sum);
    [pool drain];
    return 0;
    }

    So I'm ready to make school exercises - variable sum is declared as int in the same way we do it in C; NSLog looks similar to TRACE from MFC or just printf.

    It's Objective-C, so I have to test an object. It will look so:
    #import <Foundation/Foundation.h>

    @interface Fraction : NSObject
    {
    int numerator;
    int denominator;
    }

    -(void) print;
    -(void) setNumerator: (int) n;
    -(void) setDenominator: (int) d;

    @end

    @implementation Fraction

    -(void) print
    {
    NSLog(@"%i/%i", numerator, denominator);
    }

    -(void) setNumerator: (int) n
    {
    numerator = n;
    }

    -(void) setDenominator: (int) d
    {
    denominator = d;
    }

    @end


    int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    Fraction * fraction;
    fraction = [Fraction alloc];
    fraction = [fraction init];

    [fraction setNumerator: 1];
    [fraction setDenominator: 3];

    [fraction print];

    [fraction release];

    [pool drain];
    return 0;
    }

    The code above is self-explained. Class Fraction declared between @interface and end. It's derived from NSObject. Two member-variables numerator and denominator are declared as int between the brackets {}. Then three lines with minus sign in the beginning declare three public class methods.

    Then, in function main, the variable of type Fraction is declared as the pointer. [Fraction alloc] allocates the memory and [fraction init], obviously, initialize this object. Next lines set nominator and denominator as 1 and 3. So in Objective-C, in order to call a method we need to write [object method]. If the method is called with an argument, it should be [object method : argument].

    Line [fraction release] releases the memory.

    Now I understand the lines about pool - the first line allocates and initializes the memory and the last line frees the memory.

    It's a beginning.