27 October 2008 - 21:12Cocoa Animation in Mac OS X Tiger

Link to Apple Docs: Cocoa Drawing Guide, Animation Programming Guide

No Comments | Tags: Cocoa, Programming

27 October 2008 - 13:26Misc useful links

No Comments | Tags: Misc, Programming

25 October 2008 - 19:33Random number generator

Mersenne Twister

Versions released from 2001-2006 are GPL. versions after 2006 can be used closed source/commercial.

No Comments | Tags: Programming

25 October 2008 - 18:28Summary of Cocoa Initializer Options

The correct way to write initializers in Cocoa.

No Comments | Tags: Cocoa, Programming

2 October 2008 - 11:17Objective-C and Cocoa Notes

Quicknotes on Objective-C and Cocoa:

self - refers to this object (similar to this in C++)
super - refers to super class object (no c++ equivalent)

Later you can do

if([someObj respondsToSelector:mySelector]) {
    [someObj performSelector:mySelector withObject:self];
}

Selectors are used for Target/Action in Cocoa.

Introspection:
Determine the class of an object at runtime.

if([myClass isKindOfClass:[NSControl class]]) {
    /*true if myClass is an object of type NSControl or of any class that
     * inherits from NSControl*/

}

if([myClass isMemberOfClass:[NSControl class]]) {
    /*true if myClass is an object of type NSControl*/
}

Identity vs Equality:

if (obj1 == obj2) {
    /*same object instance*/
}

if ([obj1 isEqual:obj2]) {
    /*logically equivalent*/
}

Protocols (Formal, informal):
Adding interfaces for others to implement
To declare an informal protocol -

@interface BaseObject (MyProtocol) : NSObject
method1();
method2();
@end

Any classes that implement this protocol have to declare the methods again in their own interface files and define them along with other methods in their implementation files.

Formal protocols -
Advantages over informal protocols - can check at runtime if an objects implements a protocol.

@protocol ProtocolName
//method declarations
@end

Implementing class:
@interface ClassName: MySuperClass <protocol1, protocol2>
@end

The implementing class must import the header  where the protocol is declared. In objective-C 2.0 classes implementing a protocol are required to implement all of the methods.

Check if an object conforms to a protocol:
if ([receiver conformsToProtocol:@protocol(MyProtocol)]) {
}

Categories: Adding methods to existing classes
Example:

#import “ClassName.h”

@interface ClassName (CategoryName)
//new method names
@end

@implementstion ClassName (CategotyName)
//method definitions
@end

Foundation classes:

NSEnumerator - used to iterate over collections (NSArray, NSSet, NSDictionary
etc). A little bit like STL iterator

NSEnumerator *en;
id object;

en = [aCollection objectEnumerator];

while((object = [e nextObject]) != nil) {
}

Misc useful functions:
All these functions return a NSString*

NSUserName() - logon name of current user
NSFullUserName() - full nam of current user
NSHomeDirectory - Home dir of current user
NSHomeDirectoryForUser(NSString *userName) - home dir of specified user
NSSearchPathForDirectoriesInDomains(…) - useful function, read the docs :-)

Memory management:

Objective-C uses reference counting. Every object you create holds a counter within itself that counts the number of pointers pointing to the object. This count can be increased by sending the object a retain message and decreased by sending it a release message. When an object finally receives a release message which decreases it’s count to 0 then it is deleted.

You are responsible for releasing objects that you create using any of the following class methods (or their variants) -

alloc, copy, new

These methods return objects with count set to 1 (so you have to [object release] when you are done with the object). If you want to hold on to data returned from other methods you have to send that object a “retain” message. Later when you are done with that object you sent it a release method.

When an object is added to an array, dictionary, set etc the collection retains it. It will be sent a corresponding release message when the collection itself is released.

Obj-C 2.0 (from Leopard onwards) introduces garbage collection. Not available on Tiger

Links:
Hold Me, Use Me, Free Me
Introduction to memory management programming guide for Cocoa;

No Comments | Tags: Cocoa, Programming

30 June 2008 - 21:13Cocoa iCal Framework for Tiger

There is an iCal API available for Leopard. For Tiger there is no API but you can try using the Private framework (CALCore.framework). These frameworks are supposedly not to be used (hence private). Apple provides no documentation and updates can break your code.

Useful links:

No Comments | Tags: Cocoa, Programming

22 June 2008 - 1:19Cocoa: Archiving objects, delegating the “Application”

How do you delegate the application? In Xcode 2.5 the Interface Builder has
no object named NSApplication in the Instances tab. Apparently the icon “File’s
Owner” is the same as your application. Delegate that object to your controller
and implement any of the NSApplication delegate methods.

Archiving:

Your object must implement the NSCoding protocol to be archivable. All you have
to do is something like this:

file.h


#import < Cocoa/Cocoa.h >

#import < Foundation/NSCoder.h >

@interface FTModel : NSObject < NSCoding >

{

@public

int myInt;

NSString *myWord;

}

-(void) encodeWithCoder:(NSCoder *) coder;

-(id) initWithCoder:(NSCoder *) coder;

@end

file.m


#import "file.h"

@implementation FTModel

-(void) encodeWithCoder:(NSCoder *) coder

{

[coder encodeInt:myInt forKey:@"favNum"];

[coder encodeObject:myWord forKey:@"favWord"];

}

-(id) initWithCoder:(NSCoder *) coder

{

if(self=[super init]) {

myNum = [coder decodeIntForKey:@"favNum"] ;

//You have to retain this obj or you are in trouble

myWord = [[coder decodeObjectForKey:@"favWord"] retain];

}

return self;

}

@end

And in the place where you are going to archive the FTModel object:


FTModel *ftModel;

.

.

.

//archive object to file

[NSKeyedArchiver archiveRootObject:ftModel toFile:fileName];

//read the object

ftModel= [[NSKeyedUnarchiver unarchiveObjectWithFile:fileName] retain];

Once you implement the NSCode protocol the above calls to NSKeyedArchiver just
work.

No Comments | Tags: Cocoa, Programming

18 June 2008 - 17:33Computing parity in C

Fast way to compute the parity of a 32-bit number in C. Here is how it works:

Parity of a bit-vector is just an XOR of all bits in the vector. The first part of this function does just that - keep XORing the top half of the bit vector with the bottom half. Till we get down to 4 bits.

Then we right shift a “magic number” to get the parity. This magic number is organized so that we always get the right answer.

0×6996 in binary is 0110 1001 1001 0110

For example, if the final value of i after all the XORing is 0001 or 0010 then the parity should be 1. Thats what you’ll get when you shift the above number by 1 or 2.

Note: Instead of using the magic number you can simply continue to XOR. The magic number trick saves a couple of shift-xor operations.


  i ^= (i >> 2);
  i = (i ^ (i >>1)) & 1;


int computeParity(int i) {
  //xor top 16 bits with bottom 16 bits
  i ^= i >> 16;
  //xor top 8 bits with bottom 8 bits
  i ^= i >> 8;
  //xor top 4 bits with bottom 4 bits, mask out 4 bottom bits
  i = (i ^ (i >> 4)) & 0xf;

  //shift "magic number" to get parity
  return (0x6996 >> i) & 1;
}

No Comments | Tags: Programming