Mathieu Tozer's Dev Blog

Cocoa, the development of Words, and other software projects (including those dang assessment tasks).




Cocoa Workshop Day 3

0 comments

Today is about learning how to create a really interactive application. Graphics, archiving. Storing objects in the model and havin the view display them.
CocoaWorkshopDay3CustomView

Custom view - just a generic view, it doesn't have a class associated with it. You do this via the custom classes attribute. You could assign it to anything, but you make your own!

Quartz Debug (the flashy thing) can show what is being redrawn in your app by quartz. Use it while optimizing.

Event methods
– mouseDown:
– mouseDragged:
– mouseUp:
– mouseMoved:
– mouseEntered:
– mouseExited:
...
All these tell you the events that we can monitor and watch for.

Floating point numbers for pixel referencing makes for antialiasing and blurring of lines. Nice!

Option double click! Wow!

The receiver is always what is on the left hand side of the method call.

Make sure you know which nib file you are working on and that it corresponds to the current Xcode project!


だからこのように自分で設けて、モデルしながらプログラミングする。


Cocoa Workshop Day 2

0 comments

Today we learnt about interface builder, actions, outlets, MCV. We had a go at creating a model object for managing Person objects from yesterday. We made a simple address book.

I also finally used SVN. So now I feel more confident with repositories and such, and mwill endeavour to use it in my own projects.

KTV notes
Quicktime kit with the attributed lyrics, with multiple language support.
It would require creating a custom view so that you can overlay the lyrics on the iSight video
[]Download SVNX

Actions are associated with methods, outlets with controls.

In terms of UML, the outlets are the attributes, and the actions are connected to the methods. Think of a class diagram.

Am becoming more confident with the debugger too which is great.
Also about the organisation and structure of the class heirarchies and how to learn more about them in the documentation.

Code completion! Wow!

Core data is good for quickly prototyping something, but there are versioning issues that Apple haven't addressed. Should probably prototype using it, then implement using more traditional methods next.

Access? Isn't that a curse word?

I'll try to add a link to the


Cocoa Workshop Day 1

0 comments

Here's today's source code. It's full of comments that note what was said about each topic.
At a higher level, we learnt about creating custom classes and about using them with Foundation.
We covered memory management.

Steps to create a class:
1. Instance Variable declarations
2. getters, setters
3. description method (Use auto scripts)
4. pragma marks
5. initialiser methods
6. class methods too for initialisation
7. deallocate
8. Add things that represent the class' data in different ways.

#import

#import "PointData.h"
#import "Person.h"
//we couldn't use @class here because you need the method names.
//we use this instead of include. This means it's only included once. gives us all those things that make programming easier.


int main (int argc, const char * argv[]) { //standard c entry point.


/*this is where it starts looking different!*/
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; //this is required for mem managemnt in the command line project

//Lesson 4
// Person *p = [[Person alloc] initWithFirstName: @"Mathieu" surname:@"Tozer"];
Person *p = [[Person personWithFirstName:@"Mary" surname:@"Janes"] retain]; //Person is now effectively like a factory object. RETAIN it so that we're sure it will stick around until we conciously release it. That little doggy will wantder away - out of the autorelease pool if we don't put a leash on it!

[p setEmailAddress:@"email@mathieutozer.com"];

NSString *fullName = [p fullName];

NSLog(@"Full Name: %@", fullName);

NSLog(@"name = %@", p);

[p release];
// [fullName release]; We don't need this because an we used stringWith... in the fullName method - it implements autorelease. We would have ended up with 'double free' error from malloc.

// //creates the actual memory with alloc, and then creates the actual instance with init. This is then assigned to an
//
// // Lesson 1
// NSString * myName = @"Mathieu";
// int count =1234;
// NSLog(@"Hello, World!"); //the @ sign refers to a literal string. It's NSString short hand @"" We use it sometimes for psuedo debugging.
// NSLog(@" My Name is %@, %d", myName, count);
//
// //Lesson 2 - Strings and formatters.
// NSString * formattedString = [NSString stringWithFormat:@"%@ %d", myName, count];
// //You can create strings with a format, which is very handy for constructing strings.
// NSLog(@"%@", formattedString);
//
// //Lesson 3 - Classes and objects
// PointData * pd = [[PointData alloc] init];
// [pd setX: 1.2];
// [pd setY: 4.5];
// NSLog(@"(x,y) = (%f, %f)", [pd x], [pd y]);
// NSLog(@"%@", pd); //because we have implemented 'descriptoin' this will print something meaningful, not just a memory address.
//
// [pd release];
// pd = nil; //this is to stop the object pointing to deallocated memory so we don't blow the computer up later down the track
[pool release]; //release the pool. We've created memory, and now we're releas123ing it.
return 0;
}



/* Notes
Objective-C doesn't have a garbage collector.
build containts the bilds and the executable for the project

drwxr-xr-x 4 cocoa06 cocoa06 4096 Jul 5 09:21 build
-rw-r--r-- 1 cocoa06 cocoa06 3132 Jul 5 09:21 firstProject2.1
-rw-r--r-- 1 cocoa06 cocoa06 801 Jul 5 09:30 firstProject2.m
drwxr-xr-x 2 cocoa06 cocoa06 4096 Jul 5 09:22 firstProject2.xcodeproj <- This is actually a DIRECTORY!
-rw-r--r-- 1 cocoa06 cocoa06 168 Jul 5 09:21 firstProject2_Prefix.pch

You can have documents that are in fact folders in the Mac environment. Things can be hidden behind a document facade. Quite handy really.

The executable file is in debug!
As opposed to release.
We can have different settings for the debug and release.
Choose release and hit buld and it will be built in a release folder. There will be some warnings that we'll discuss later.

Objective-C is designed for you to be a bit more verbose than you usually might be.
you put the label right beside the variable.
You write the method name in a way to describe the first varable.

To make things a bit more confusing, you can just call C functions too.
That's the interesting thing about having a language that is a superset of another language.

Language additions:
id
This is similar to a void* We can let it be assigned to any object. A very dynamic language, and it encourages that.
self
This is an OO concept.
@interface and @inplementation are like block indicators. Used when defining a class.
@protocol allows you to define a series of methods that you would like an interface to adopt.
You can use this to say something like "This class MUST implement mouseDown.

@class
You use this to tell a class that there will be an object of this kind somewhere at runtime - then you can use them and their methods.
These cannot access instance variables.
+(id)createNewObject:
+(id)createObjectOfSize:(int)size;
These are class methods that cannot access instance varables. You'd use these when you're creating factory objects.

In fact, IBAction and IBOutlet aren't part of Objective-C. They're used by interface builder to figure out what goes where.

We can turn on warnings. gcc is very much in the background of Xcode.
We can also look at the actual textual input output of gcc from within the application (the little texty looking button).

NSString *list = @"wrenches, hammers, saws";
NSArray *listItems = [list componentsSeparatedByString:@", "];

This method is handy for parsing!!!

What we've learnt today....
alloc -> rc = 1
release => rc= rc+1
retain => rc = rc +1
autorelease => rc = rc -1 disposed of "later" NSAutoreleasePool

You have to match these up
alloc copy retain
----
release autorelease
*/

//
// PointData.h
// firstProject2
//
// Created by , on 5/07/06.
// Copyright 2006 __MyCompanyName__. All rights reserved.
//

#import
/*!
@class
@abstract Stores a point
@discussion A point contains an x y value
*/ //This is a script to auto generate documentation

//single inheritance - one class only!!
@interface PointData : NSObject {
//member variables
float x;
float y;
}
//methods - in order to get access to x and y.
//so we have this concept called accessors, these give us the ability to get and set the variable.

//the convention is to just ask for the variable name. This is also to enable some of Apple's automatic stuff. Handy.
-(float)x;
-(void)setX:(float)value;
-(float)y;
-(void)setY:(float)value;

//returns a string that contains a description Good practice to define them here so that your code is readable.
- (NSString *) description; //Pretty print!

//There, now we have an interface that gives us access our variables.


@end

//Use split views to have imp and inter in the same window.
//Command / comments whole highlighed blocks
//K for compile!


//Sometimes you can't see the warnings, like incomplete implementation of a method. You should check the Errors and Warnings section of Xcode for these.

//
// PointData.m
// firstProject2
//
// Created by , on 5/07/06.
// Copyright 2006 __MyCompanyName__. All rights reserved.
//

#import "PointData.h"

#pragma mark Accessors
@implementation PointData

-(float)x{
return x;
}
-(void)setX:(float)value{
x = value;
}
-(float)y{
return y;
}
-(void)setY:(float)value{
y = value;
}

//returns a string that contains a description
- (NSString *) description{
return [NSString stringWithFormat: @"(%f, %f)", [self x], [self y]]; //this returns an object which is a string. It is an autorelease object
}
@end


//
// Person.h
// firstProject2
//
// Created by , on 5/07/06.
// Copyright 2006 __MyCompanyName__. All rights reserved.
//

#import


@interface Person : NSObject {
NSString *first;
NSString *surname;
NSString *emailAddress;

}
+ (Person *) personWithFirstName: (NSString *) aFirstName surname:(NSString *)aSurname;
- (id)initWithFirstName: (NSString *) aFirstName surname:(NSString *)aSurname;
- (NSString *)firstName;
- (void)setFirstName:(NSString *)aName;
- (NSString *)surname;
- (void)setSurname:(NSString *)aName;
- (NSString *)emailAddress;
- (void)setEmailAddress:(NSString *)aEmailAddress;

-(NSString *)fullName;

@end

//
// Person.m
// firstProject2
//
// Created by , on 5/07/06.
// Copyright 2006 __MyCompanyName__. All rights reserved.
//

#import "Person.h"


@implementation Person

#pragma mark Class Methods
//Lesson 5 This is the neatest way of initialising objects.
+ (Person *) personWithFirstName: (NSString *) aFirstName surname:(NSString *)aSurname {
Person * p;
p = [[Person alloc] initWithFirstName:aFirstName surname:aSurname];
return [p autorelease]; //we want to release it, but we want it to stick around for a bit!
}

#pragma mark Initialisers
// designated initialiser
- (id)initWithFirstName: (NSString *) aFirstName surname:(NSString *)aSurname{
self = [super init];
if(nil!= self){
[self setFirstName:aFirstName];
[self setSurname:aSurname];
}
return self;
}

- (id) init {
self = [super init];
if (nil != self) {
[self setFirstName:@""];
[self setSurname:@""];
[self setEmailAddress:@""];
}
return self;
}
#pragma mark Dealloc
- (void) dealloc {
[first release];
[surname release];
[emailAddress release];
[super dealloc]; //not super release!! You'd release NSOject!!
}

#pragma mark Accessors
- (NSString *)firstName{
return [[first retain] autorelease];
}
- (void)setFirstName:(NSString *)aName{
if (first != aName){
[first release];
first = [aName copy]; //see notes in moleskein about why this is so. You need to make a copy, rather than pointing to the original object
}
}
- (NSString *)surname{
return [[surname retain] autorelease]; //retain youself! But autorelease yourself later ;-) There's a balance here - we're not actually changing the net value of it's retain count at all! Up one, then a little later down one. The reciever can do what he wants with it (usually retain).
}
- (void)setSurname:(NSString *)aName{
//what if aName and surname are actually pointing to the same object?? Then we have to check
if (surname != aName){
[surname release];
surname = [aName copy]; //see notes in moleskein about why this is so. You need to make a copy, rather than pointing to the original object
}
}

- (NSString *)emailAddress{
return [[emailAddress retain] autorelease];
}
- (void)setEmailAddress:(NSString *)aEmailAddress{
if(emailAddress != aEmailAddress){
[emailAddress release];
emailAddress = [aEmailAddress copy];
}
}

#pragma mark String Operations
-(NSString *)fullName{
return [NSString stringWithFormat:@"%@ %@", [self firstName], [self surname]]; //we're taking advantage of the fact that this is already autoreleased.
}

- (NSString *)description{
return [NSString stringWithFormat: @"first=%@ surname=%@ emailAddress=%@",
[self firstName],
[self surname],
[self emailAddress]];
}


@end


#import
#import "Person.h"

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


//NSArray *myArray = [[NSArray arrayWithObjects:@"One", @"Two", @"Three", nil] retain]; //we're passing arbitary objects into the array. Just string 'em up!
//when an object is passed to an array, NSArray is retaining the object
//If you want programattic control, then you can use an NSMutableArray
NSMutableArray * myMutableArray = [NSMutableArray array];
//NSDictionary *fontAttributes = [NSDictionary dictionaryWithObject:[NSNumber numberWithDouble:12.0] forKey:@"MyNumber"];//when we want to write pretty strings to the screen, we need to pass font attributes


int i;
Person *p = [Person personWithFirstName:@"Mathieu" surname:@"Tozer"];
Person *q = [[Person alloc] initWithFirstName:@"Carlo" surname:@"Marasea"];
for(i=0; i<10; i++){
NSString *str = [NSString stringWithFormat: @"cocoa %d", i];
[myMutableArray addObject:str];
if (i == 5){
[myMutableArray addObject:p];
[myMutableArray addObject:q];
[q release];
q =nil;
}
// [myMutableArray addObject:[[str copy] autorelease]]; if you want to put a copy in - otherwise ARRAYS ARE RETAINING.
}
[myMutableArray addObject:[NSNumber numberWithFloat:3.7348]]; //we need a wrapper to store the data. Seems like baggage, but when we come to things like saving, this will make our lives a whole lot easier.

NSEnumerator *e = [myMutableArray objectEnumerator]; //so now there is an object that will allow us to enumerate the array
id obj;
while(obj = [e nextObject]) { //we are deliberately assigning the objects of the array to obj
if([obj isKindOfClass:[NSNumber class]]){
NSLog(@"number found >>>>>> %@", obj);
}
else{
NSLog(@"%@", obj);
}
}

// insert code here...

[pool release];
return 0;
}


//leart how to do auto code completion which reduces errors, and also allows me to think at a conceptually higher level than was previously possible.


+RSS | dev blog | Portfolio

About me

My status

Last posts

  • my del.icio.us
  • my flickr