Cocoa tutorial – linking and using libmysqlclient in your application

Here’s a little tutorial on how to use libmysqlclient in a Cocoa application.

First of all you need to create a new Xcode project; suppose to create it in the directory: /path/to/your/project/.

Then you need to retrieve the libmysqlclient.aand libmysqlclient_r.afiles located in the /usr/local/mysql/lib/default directory. To do this you can, for example, start a new Terminal session and type the following commands:

cp/usr/local/mysql/lib/libmysqlclient.a /path/to/your/project/cp/usr/local/mysql/lib/libmysqlclient_r.a /path/to/your/project/

Now go to Xcode and select “Project” -> “Edit Project Settings” in the main menu. Now select the “Build” tab and make the following changes to all your configurations (Debug and Release):

  • “Architectures”: the same of your libmysqlclient architecture;
  • “Valid Architectures”: architectures compatibles with your libmysqlclient architecture(s);
  • “C/C++ Compiler Version”: GCC 4.2;
  • uncheck “Prebinding”;
  • turn on (if desired) the “Objective-C Grabage Collection”;
  • “C Language Dialect”: C99 [-std=c99];
  • check “Mismatched Return Type”;
  • check “Unused Variables”.

Note that not all of these flags are strictly required for the correct use of libmysqclient.aand libmysqlclient_r.a; you can test them and see what happens when you change some of them.

Now you need to import the libraries. To do so, right click on the group “Frameworks” located in the “Groups & Files” tree in Xcode and select “Add” -> “Existing Frameworks…”. Locate the libmysqlclient.afile and click the Add button. Repeat the operation with the libmysqlclient_r.afile.

Now you need to tell Xcode to copy the two libraries in the bundle directory. To do so, you must create a new copy build phase in your target and put the libraries in it:

  • Expand the “Targets” group in the “Groups & Files” tree;
  • right click on your application and select: “Add” -> “New Build Phase” -> “New Copy Files Build Phase”;
  • in the new window select “Frameworks” in the Destination popup menu;
  • close the window;
  • drag and drop the libmysqlclient.aand libmysqlclient_r.afiles from the Frameworks group to the new “Copy Files” group.

Now you need to copy all the MySQL C API headers in your project directory. To do so you can, for example, do something like this:


That’s all. To access any MySQL API function, you only need to import the mysql.hand unistd.h

Here’s a short example on how to use the API in a .m file:

... #include "mysql.h"#include "unistd.h"  @implementationAppController   ...   -(void)connect {MYSQL conn; mysql_init(amp;conn);   if(!mysql_real_connect(amp;conn, "", "", "", "", 0, NULL, 0))NSLog(@"%s", [NSStringstringWithUTF8String:mysql_error(amp;conn)]); elseNSLog(@"Connected"); }@end

Download the test project.

출처 :
Posted by 오늘마감

댓글을 달아 주세요

아이폰어플개발정보2010. 10. 16. 05:25
[아이폰 앱 개발] Cocoa for Scientists (XXIV): Core Animation First Steps

Cocoa for Scientists (XXIV): Core Animation First Steps

Author: Drew McCormack
Web Site:

Arguably the most important change in Leopard was not a user feature, but a developer one: Core Animation. Over the coming years, the way applications look and react to user interaction will change dramatically, and that will be largely due to the ease with which interfaces can be animated with Core Animation. Sure, there will also be overt eye candy, but there will also be lots of more subtle changes to application interfaces that truly benefit the user, giving useful feedback.

Core Animation is obviously an enormous boon for user interface developers, but it has other uses too, such as visualization. There are many scientific applications for which Core Animation could be very useful. In the next few tutorials, I want to introduce Core Animation, and show its potential for scientific visualization. I won’t be showing you how to create the CoverFlow effect, or reprogram the Front Row application, but will hopefully introduce you to a whole new way of looking at Core Animation.

What is Core Animation?

It is easy to get confused about what exactly Core Animation is, because it is an umbrella for several different types of functionality. And what makes it more confusing is that developers can use it implicitly with CocoaNSView objects to animate their UIs. These views are called layer-backed views, and strictly speaking are not part of Core Animation itself, but do make use of it.

In addition to programming in Cocoa with layer-backed views, you can also program directly with Core Animation classes. Core Animation combines a number of different aspects. First there is animation: Core Animation can animate a property (e.g. position, opacity, orientation) in time. It performs this animation on a dedicated thread, so the animation goes on even if the hardware can’t keep up — Core Animation will simply drop frames to make sure that the animation finishes on time.

The second important aspect of Core Animation is layering. (While still in the pre-release phase, Core Animation was even called ‘Layer Kit’, and Core Animation classes had an ‘LK’ prefix.) Layers are a bit like Cocoa views, but they exist in three-dimensional space. They are rectangular, and can hold assorted content, such as OpenGL renderings, QuickTime movies, images, and text. Each layer can hold different content, and can be superimposed, meaning you can effectively combine different types of content in a single view. For example, you could place some controls on top of a playing QuickTime movie, or have an 2D image appear next to an OpenGL rendering.

So Core Animation is not simply animation, but layers and animation. And the two work beautifully in harmony. For example, set the position of a layer and it animates to the new position, all the while presenting its content. A QuickTime movie will continue to play, and an OpenGL view continue to animate (if it is an animated rendering).

What is it not?

The 3D nature of Core Animation can also be a bit confusing. Don’t we already have that? Isn’t it called OpenGL?

Core Animation is not a 3D engine, and in that sense it should probably be called 2.5D. Layers do have a position along the Z axis, which comes out of the screen, but if two layers intersect, Core Animation will not do the math to make sure things look ‘right’. Better not to let layers intersect.

Another thing to remember is that layers are not polygons. In OpenGL, it is easy to build up an arbitrary surface out of polygonal pieces, but layers are rectangular, and cannot represent arbitrary surfaces. Layers provide a 2D canvas that moves in a 3D space, and are not appropriate for representing true 3D objects. For that you need OpenGL.

The Fleas on the Fleas

To introduce you to Core Animation, I’m going to develop a simple application called ‘Flea on Flea’. When complete, this app will have lots of Core Animation layers — the fleas — moving around on parent layers — the other fleas — in a recursively animated collage.

Sound enticing? Well, you will have to wait, because this week we are only going to get up to animating a simple square on a black background. Although this might not sound too exciting, at the end of the tutorial, you will already have seen many of the most important aspects of Core Animation programming.

Before embarking on the tutorial proper, I suggest you download the finished app, and see how it works. There is no interaction in the application — it is simply an animated scene. If you want to follow along, download the source code too.

The Layer Hosting View

The first thing you need to do before you can start generating and animating layers is to provide a container for them in the user interface. This is just an ordinary NSView that has a special backing layer, and is known as the hosting view. You can see how such a hosting view can be configured in the setupHostView method of the Flea on Flea controller class FFController.

-(void)setupHostView { CALayer *layer = [CALayer layer]; CGColorSpaceRef colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB); CGFloat components[4] = {0.0f, 0.0f, 0.0f, 1.0f}; CGColorRef blackColor = CGColorCreate(colorSpace, components); layer.backgroundColor = blackColor; [hostView setLayer:layer]; [hostView setWantsLayer:YES]; CGColorRelease(blackColor); CGColorSpaceRelease(colorSpace); }

A layer in Core Animation is represented by the CALayer class. To use the Core Animation classes, you need to add the QuartzCore framework to your project, and import the QuartzCore.h header.

#import <QuartzCore/QuartzCore.h>

You can use a vanilla CALayer instance as the backing layer, as shown above, but there are also several different subclasses of CALayer, which could be useful if you need to render something more substantial in your hosting view. For example, if you want to have some OpenGL content in the hosting view, back it with a CAOpenGLLayer. (Note that just because you use a CAOpenGLLayer, does not mean your view has to be an NSOpenGLView. In general, you should just use a plain NSView object, and it should not do any drawing of its own.)

Setting the backing layer of the hosting view is simple: you just use the setLayer: method, and make sure that you call setWantsLayer: passing in the argument YES.

[hostView setLayer:layer]; [hostView setWantsLayer:YES];

That’s often all there is to creating a backing layer, but in Flea on Flea we want to set the background color to black. To do that, we create a CGColor and set the backgroundColor property of the layer.

CGColorSpaceRef colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB); CGFloat components[4] = {0.0f, 0.0f, 0.0f, 1.0f}; CGColorRef blackColor = CGColorCreate(colorSpace, components); layer.backgroundColor = blackColor; ... CGColorRelease(blackColor); CGColorSpaceRelease(colorSpace);

The QuartzCore framework is quite low level, so you usually have to work with Core Graphics types and primitives, rather than Cocoa objects. For example, in the code above, a CGColor is created, rather than anNSColor. This can be a bit ungainly, because you have to worry about memory management and old-fashioned stuff like that, but you soon get used to it. Just remember that when you create a Core Graphics type, make sure you release it when you are finished with it.

Adding Sublayers

With a hosting view in place, we can now add sublayers that move around in the host. Flea on Flea uses thecreateFleaLayerInLayer: method for this, which is called once from awakeFromNib.

-(void)awakeFromNib { [self setupHostView]; [self createFleaLayerInLayer:hostView.layer]; ... }

createFleaLayerInLayer: adds a sublayer to the layer passed in, which in this case is the host view backing layer.

-(void)createFleaLayerInLayer:(CALayer *)parentLayer { CGColorSpaceRef colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB); CALayer *layer = [CALayer layer]; CGRect frame = parentLayer.bounds; frame.origin.x += 20.0f; frame.size.width = parentLayer.bounds.size.width / 10.0f; frame.size.height = frame.size.width; layer.frame = frame; CGFloat components[4] = {1.0f, 1.0f, 1.0f, 1.0f}; CGColorRef whiteColor = CGColorCreate(colorSpace, components); layer.backgroundColor = whiteColor; [parentLayer addSublayer:layer]; CGColorRelease(whiteColor); CGColorSpaceRelease(colorSpace); }

The new layer is created in the same way as the backing layer was, and the background color set to white. A layer has similar geometric properties to an NSView, such as a frame, which gives the size and position of the layer in its parent’s coordinate system, and bounds, which delineate positions in the layers own coordinates. IncreateFleaLayerInLayer:, the bounds of the parent layer are used to size the new sublayer. The new layer is made a tenth the size of the width of the parent layer, and positioned to the right of the parent layer’s origin (in the lower-left corner).

CGRect frame = parentLayer.bounds; frame.origin.x += 20.0f; frame.size.width = parentLayer.bounds.size.width / 10.0f; frame.size.height = frame.size.width; layer.frame = frame;

The addSublayer: method adds the new layer to the parent.

[parentLayer addSublayer:layer];

If you run Flea on Flea with only this code in place, it will draw a white square on a black background, but nothing will change. In the next section, we will see how to animate the square.

Animating Layers

In the very simple Flea on Flea example, the white sublayer will be made to move to random locations, as well as scale and rotate. There will be no user interaction, but the layer could easily be made to respond to mouse clicks or some other interaction.

In the awakeFromNib method, a timer is started to repeatedly invoke the changeDestination method every 2 seconds.

-(void)awakeFromNib { ... [NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(changeDestination) userInfo:nil repeats:YES]; }

The changeDestination method chooses random values for the position of the sublayer, and its orientation, and starts an animation to move the layer toward those destination values.

-(void)changeDestination { [CATransaction begin]; [CATransaction setValue:[NSNumber numberWithFloat:3.0f] forKey:kCATransactionAnimationDuration]; CALayer *layer = hostView.layer.sublayers.lastObject; layer.position = CGPointMake(hostView.bounds.size.width * rand()/(CGFloat)RAND_MAX, hostView.bounds.size.height * rand()/(CGFloat)RAND_MAX); CGFloat factor = rand()/(CGFloat)RAND_MAX * 2.0f; CATransform3D transform = CATransform3DMakeScale(factor, factor, 1.0f); transform = CATransform3DRotate(transform, acos(-1.0f)*rand()/(CGFloat)RAND_MAX, rand()/(CGFloat)RAND_MAX, rand()/(CGFloat)RAND_MAX, rand()/(CGFloat)RAND_MAX); layer.transform = transform; [CATransaction commit]; }

When you change properties of CALayer objects, the layer will automatically animate to the new values. So if you entered this in a program

layer.position = CGPointMake(50.0, 50.0);

the layer would fly to the new position. This is known as implicit animation. But what we have above inchangeDestination is an example of explicit animation. When you use explicit animation, you use a CATransactionto group together a series of property changes, and set properties of the animation. A transaction begins with a call to the begin class method

[CATransaction begin];

and ends when the commit method is invoked.

[CATransaction commit];

In between you can set properties for the layers involved. The changeDestination method sets the position of the layer, and its transform property.

CALayer *layer = hostView.layer.sublayers.lastObject; layer.position = CGPointMake(hostView.bounds.size.width * rand()/(CGFloat)RAND_MAX, hostView.bounds.size.height * rand()/(CGFloat)RAND_MAX); ... layer.transform = transform;

The transform has the CATransform3D type, and involves a random scaling of the layer, and a random rotation.

CGFloat factor = rand()/(CGFloat)RAND_MAX * 2.0f; CATransform3D transform = CATransform3DMakeScale(factor, factor, 1.0f); transform = CATransform3DRotate(transform, acos(-1.0f)*rand()/(CGFloat)RAND_MAX, rand()/(CGFloat)RAND_MAX, rand()/(CGFloat)RAND_MAX, rand()/(CGFloat)RAND_MAX);

The CATransform3DMakeScale function creates a transform that has scaling factor arguments for x, y, and z. TheCATransform3DRotate function applies a rotation to the transform passed in as first argument; the rotation is through an angle (in radians) passed as the second argument, around a vector (x, y, z) passed as the last three arguments.

The duration of the animation will be 0.25 seconds by default, but this can be changed by setting a value of the CATransaction class

[CATransaction setValue:[NSNumber numberWithFloat:3.0f] forKey:kCATransactionAnimationDuration];

Note that the animation has been set to take 3.0 seconds, but the timer that changes the destination fires every 2.0 seconds. In other words, the animation will not be able to complete before the timer starts a new animation. Can Core Animation cope with this? No problem.

Running Flea on Flea

If you downloaded the Flea on Flea Xcode project, build and run it. You should see a white square dancing across the screen, rotating and scaling as it goes. Note how it moves for 2 seconds, then changes direction. Core Animation interrupts any existing animations, and smoothly modifies the motion of the square to accommodate the new destination. Try changing the duration of the animation and the timer in the source code, to see what effect it has on the way the square moves.

Further Reading

Next time we will make Flea on Flea live up to its name, by adding layers, on layers, on… Until then, you can read more about Core Animation in the Core Animation Programming Guide, and in a new book by Bill Dudney which is still in beta at The Pragmatic Programmers.

Posted by 오늘마감

댓글을 달아 주세요

아이폰어플개발정보2010. 10. 15. 19:32
[아이폰 앱 개발] Cocoa for Scientists (Part XXV): Core Animation Layer Trees

Cocoa for Scientists (Part XXV): Core Animation Layer Trees

Author: Drew McCormack
Web Site:

In the first part of this foray into Core Animation, we saw how you can animate the properties of a plain square layer, translating, scaling, and rotating in time. In this part, you’ll learn how to build up hierarchies of layers — the proverbial fleas on the fleas. To do this, we’ll finish off the Flea on Flea application, adding sublayers that creep and crawl on the backs of their superlayers, which in turn creep and crawl on the backs of theirs.

Flea on Flea

The Flea on Flea application (requires Mac OS X 10.5) is nothing more than an animated scene, but it demonstrates how you build up a layer tree: a hierarchy of child layers and their parents. Each flea layer in the application has other, smaller flea layers randomly walking its surface. You can’t interact with the scene, but you can resize the window to give the fleas more room to move.

The Flea on Flea application.

Flea on Flea is a fun way to be introduced to the layer tree, but you don’t have to think too hard to come up with scientific applications which utilize the same basic approach. Multi-scale is a trendy catch phrase in many fields, and with a bit of creativity, it should be possible to come up with some revolutionary new ways of navigating hierarchical data sets with Core Animation layer trees.

The Layer Tree

Much like NSViewCALayers can be organized into a tree structure, with sublayers in superlayers, in super-superlayers, and so on. Just as for NSView, each layer moves in the coordinate system of its superlayer, which is given by the bounds property. The size and location of a layer relative to its superlayer is determined by itsbounds rectangle, and its position, which is a point giving the location of the anchor point in the superlayer’s coordinate system. The anchor point is the point which represents the center of the layer’s world, which remains fixed during transformations like rotation and scaling. By default, the anchor point is at the center of the layer, but it can be moved by setting the anchorPoint property.

The geometry of a CALayer (image from Core Animation Programming Guide).

There are many similarities between NSView and CALayer, but also some subtle differences. For example, CALayerdoes not crop its sublayers drawing by default. If you want this behavior, you need to set the layer’s propertymasksToBounds to YES. Layers also have a few tricks that views don’t, such as the ability to set a background color (backgroundColor property); round corners (cornerRadius property); draw a drop shadow (shadowOpacity,shadowOffsetshadowRadius, and shadowColor); and include a border (borderWidth and borderColor). You can even set Core Image filters to change the appearance of the layer’s content, or whatever lies directly behind it (eg. you could blur the background).

Flea on Flea with random background colors and rounded corners.

Growing the Tree

The Flea on Flea source code is not much more advanced than it ended up last time. The awakeFromNib method downloads an image of a flea, and stores it in an instance variable.

-(void)awakeFromNib { // Download flea image NSURL *url = [NSURL URLWithString:@""]; CGImageSourceRef imageSource = CGImageSourceCreateWithURL((CFURLRef)url, NULL); fleaImage = CGImageSourceCreateImageAtIndex(imageSource, 0, NULL); CFRelease(imageSource); // Setup layers [self setupHostView]; [self createFleas]; // Start Timer [NSTimer scheduledTimerWithTimeInterval:3.0 target:self selector:@selector(changeDestinations) userInfo:nil repeats:YES]; }

As usual, Core Graphics types and functions are used; in this case, a CGImageSource is used to download an image from a URL, and create a CGImage, which is the image type used in Core Animation.

The awakeFromNib method continues by calling a method to setup the host view, which is unchanged from last time, and to initialize the flea layers and build the layer tree.

The createFleas method creates an array to store references to all of the flea layers, and then calls another routine to do the hard work.

-(void)createFleas { allFleaLayers = [NSMutableArray array]; [self createFleasInLayer:hostView.layer atDepth:0]; }

createFleasInLayer:atDepth: is a function that is designed to be called recursively. It adds a new sublayer to the layer passed in, and then recursively calls itself to add its own sublayers, up to a maximum layer depth.

-(void)createFleasInLayer:(CALayer *)layer atDepth:(NSUInteger)depth { static const NSUInteger MAX_DEPTH = 2; static const NSUInteger NUMBER_FLEAS_PER_LAYER = 4; if ( depth > MAX_DEPTH ) return; NSUInteger fleaIndex; for (fleaIndex = 0; fleaIndex < NUMBER_FLEAS_PER_LAYER; ++fleaIndex) { CALayer *newLayer = [self createFleaLayerInLayer:layer]; [allFleaLayers addObject:newLayer]; [self createFleasInLayer:newLayer atDepth:depth+1]; } }

Each flea layer is initialized in the createFleaLayerInLayer: method.

-(CALayer *)createFleaLayerInLayer:(CALayer *)parentLayer { CALayer *layer = [CALayer layer]; // Choose random location in parent layer float rand1 = rand()/(float)RAND_MAX; float rand2 = rand()/(float)RAND_MAX; float parentWidth = CGRectGetWidth(parentLayer.bounds); float parentHeight = CGRectGetHeight(parentLayer.bounds); layer.position = CGPointMake(rand1*parentWidth, rand2*parentHeight); layer.bounds = CGRectMake(0.0, 0.0, parentWidth*0.4, parentHeight*0.4); layer.opacity = 0.9; // Set image layer.contents = (id)fleaImage; // Add to parent [parentLayer addSublayer:layer]; return layer; }

The layer is given a random position in the bounds of its superlayer. Its contents property is set to theCGImageRef created in awakeFromNib, and the layer opacity set to 0.9 (to give it that icky translucence popular with small insects).

That’s almost all there is to it. The only aspect remaining is the animation itself. A timer, which is created inawakeFromNib, fires every 3 seconds, and invokes the changeDestinations method. This method loops over all flea layers, assigning a random position and rotation around the z-axis.

-(void)changeDestinations { [CATransaction begin]; [CATransaction setValue:[NSNumber numberWithFloat:3.0f] forKey:kCATransactionAnimationDuration]; for ( CALayer *layer in allFleaLayers ) { // Choose a random position in the superlayer layer.position = CGPointMake(layer.superlayer.bounds.size.width * rand()/(CGFloat)RAND_MAX, layer.superlayer.bounds.size.height * rand()/(CGFloat)RAND_MAX); // Choose a random rotation around the z axis CATransform3D transform = CATransform3DIdentity; transform = CATransform3DRotate(transform, acos(-1.0)*rand()/(CGFloat)RAND_MAX, 0.0, 0.0, 1.0); layer.transform = transform; } [CATransaction commit]; }

Being Core Animation, these changes don’t take effect immediately, but provide a target for the animation. The code to setup and commit the CATransaction is exactly the same as last time.

Things to Try

Flea on Flea is a fun application to play with. You can quite easily modify aspects of it to change the appearance and behavior of the flea layers. For example, if you want to add a colored drop shadow to the fleas, you could change the createFleasInLayer:atDepth: method as follows:

-(void)createFleasInLayer:(CALayer *)layer atDepth:(NSUInteger)depth { static const NSUInteger MAX_DEPTH = 2; static const NSUInteger NUMBER_FLEAS_PER_LAYER = 4; if ( depth > MAX_DEPTH ) return; NSUInteger fleaIndex; for (fleaIndex = 0; fleaIndex < NUMBER_FLEAS_PER_LAYER; ++fleaIndex) { CALayer *newLayer = [self createFleaLayerInLayer:layer]; // Set the shadow color based on depth CGColorSpaceRef colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB); CGFloat components[4] = {0.0f, 0.0f, 0.0f, 1.0f}; switch (depth) { case 1: components[1] = 1.0f; break; case 2: components[2] = 1.0f; break; case 3: components[0] = 1.0f; components[1] = 1.0f; components[2] = 1.0f; break; } CGColorRef color = CGColorCreate(colorSpace, components); newLayer.shadowColor = color; newLayer.shadowOpacity = 0.5; newLayer.shadowRadius = 2.0; newLayer.shadowOffset = CGSizeMake(0.0, 0.0); CGColorRelease(color); CGColorSpaceRelease(colorSpace); [allFleaLayers addObject:newLayer]; [self createFleasInLayer:newLayer atDepth:depth+1]; } }

It’s also worth observing the effect of setting the masksToBounds property of new layers to YES, as this is a one line change.

Flea on Flea with a Core Image Bloom filter applied to each layer.

Lastly, there are a multitude of Core Image filters that can be applied. Here’s how you can modifycreateFleaLayerInLayer: to apply a bloom effect to the fleas.

-(CALayer *)createFleaLayerInLayer:(CALayer *)parentLayer { CALayer *layer = [CALayer layer]; // Choose random location in parent layer float rand1 = rand()/(float)RAND_MAX; float rand2 = rand()/(float)RAND_MAX; float parentWidth = CGRectGetWidth(parentLayer.bounds); float parentHeight = CGRectGetHeight(parentLayer.bounds); layer.position = CGPointMake(rand1*parentWidth, rand2*parentHeight); layer.bounds = CGRectMake(0.0, 0.0, parentWidth*0.4, parentHeight*0.4); layer.opacity = 0.9; // Set image layer.contents = (id)fleaImage; // Set Core Image filter CIFilter *bloomFilter = [CIFilter filterWithName:@"bloom"]; if ( nil == bloomFilter ) { bloomFilter = [CIFilter filterWithName:@"CIBloom" keysAndValues: kCIInputRadiusKey, [NSNumber numberWithFloat:1.0], kCIInputIntensityKey, [NSNumber numberWithFloat:10.0], nil]; = @"bloom"; } layer.filters = [NSArray arrayWithObject:bloomFilter]; // Add to parent [parentLayer addSublayer:layer]; return layer; }

Be warned: filters and drop shadows seem to be demanding on the graphics hardware, and you might want to reduce the MAX_DEPTH and/or NUMBER_FLEAS_PER_LAYER constants before using them.

Posted by 오늘마감

댓글을 달아 주세요

아이폰어플개발정보2010. 6. 24. 14:13
Memory Management Programming Guide for Cocoa

- garbage collected environment: Mac OS X 10.5+

- reference counted environment: iPhone OS

Object ownership policy: responsibility for disposal

** policy **

- You own any object you create (alloc, new, copy)

- If you own an object, you are responsible for relinquishing ownership when you have finished with it.

- If you do not own an object (convenience constructor), you must not release it.

// typical good example

Thingamajig *thingamajig = [[Thingamajig alloc] init];

// ...

NSArray *sprockets = [thingamajig sprockets];

// ...

[thingamajig release];

// typical wrong example

// 1 - convenience method

Thingamajig *thingamajig = [Thingamajig thingamajig];

[thingamajig release]; // wrong

// 2 - function loses the chance to release

+ (Thingamajig *)thingamajig {

    id newThingamajig = [[Thingamajig alloc] init];

    return newThingamajig;


// 3 - no owner, disposed before returned

+ (Thingamajig *)thingamajig {

    id newThingamajig = [[Thingamajig alloc] init];

    [newThingamajig release];

    return newThingamajig; // newThingamajig is invalid here


autorelease - you declare that you don't want to own the object beyond the scope in which you sent autorelease.

– (NSArray *)sprockets {

    NSArray *array;

    array = [[NSArray alloc] initWithObjects:mainSprocket,

                               auxiliarySprocket, nil];

    return [array autorelease];


strong reference: pointer which retaining the object

weak reference: pointer that doesn't (usually to avoid mutual retaining each other) ex) table data sources,outlineview items,notification observers,and miscellaneous targets and delegates

** holder of weak reference SHOULD be notified when the objected is deallocated. **

** Don't piggy-back resource management on top of dealloc.

You should typically not manage scarce resources such as file descriptors,network connections,and buffers / caches in a dealloc method.Invocation of dealloc might be delayedor side stepped.

When you add an object to a collection such as an array,dictionary,or set,the collection takes ownership ofit.

** autorelease pools **

Anautorelease pool is an instance of NSAutoreleasePool that “contains” other objects that have receivedan autorelease message;when the autorelease poolis deallocated it sends a release message to eachof those objects. An object can be put into an autorelease pool several times, and receives a release messagefor each time it was put into the pool.

If you send an autorelease message when a poolis not available,Cocoa logs a suitable error message.

Autorelease pools are arranged in a stack,although they are commonly referred to as being "nested." When an object is sent an autorelease message, it is added to the current top mostpoolfor the current thread.

If you spawn a secondary thread,you must create your own autorelease poolas soon as the thread begins executing.


Ifyoureleaseanautoreleasepoolthatisnotthetopofthestack,thiscausesall(unreleased)autorelease poolsaboveitonthestacktobereleased,alongwithalltheirobjects.

in garbaged collected environment

- release: no-op

- drain of autorelease pool: triggers garbage collection (if the last collection > current threshold)

Youshouldusedrainratherthanreleaseto disposeofanautoreleasepool.


Zonesarepage-alignedareasofmemorythatholdtheobjectsanddataallocatedbyanapplication. Thesystemassignseachapplicationa“default”zoneinitiallyandapplicationscancreateadditionalzoneslater.

출처 :

'아이폰어플개발정보' 카테고리의 다른 글

iPhone Games Projects  (0) 2010.06.24
The iPhone Developers Cookbook  (0) 2010.06.24
Memory Management Programming Guide for Cocoa  (0) 2010.06.24
iPhone Development Guide  (0) 2010.06.24
Quartz2D로 한글 그리기..  (0) 2010.06.24
맥에서 화면 녹화하기  (0) 2010.06.24
Posted by 오늘마감

댓글을 달아 주세요

아이폰어플개발정보2010. 6. 21. 09:29
[펌] Cocoa 에서 MySQL 라이브러리 사용하기
출처 -

코아에서 MySQL C Library를 이용하는 예입니다. wrapper 클래스를 작성하여 MySQL
서버에 접속해서 데이터를 가져오는 간단한 샘플 코드를 작성해 보겠습니다.

OS X에서 MySQL 설치 및 설정은 이전 포스트를 참고해 하세요.

1. MySQL에서 작업

1) MySQL 서버 확인
테스트를 위하여 테이블을 생성하고 데이터를 넣어 보겠습니다. 우선 시스템 환경설정의 MySQL 항목에서 아래와 같이 서버가 기동중인지 확인 합니다. 서버가 실행되지 않고 있으면 Start 버튼을 클릭하여 아래와 같이 실행 상태로 만듭니다.

2) 테이블 생성 및 데이터 입력
그 다음 아래와 같이 터미널에서  MySQL에 로그인 후에 member 테이블을 생성하고 데이터를 넣습니다. 저는 이전에 test/1111로 계정을 만들고 cocoadev란 데이터베이스를 만들어 두었기에 아래와 같이 접속하였습니다.

id, name 두개의 필드를 가진 member란 테이블을 생성하고, 테스트를 위해 1, cocoa 값으로 데이터를 입력합니다.

2. 소스코드 작성
Xcode 를 실행하고 프로젝트를 생성합니다. 저는 최대한 간단하게 만들기 위해 프로젝트 타입을 Command Line Utility의 Foundation Tool로 선택하고 프로젝트를 생성하였습니다.

Wrapper 클래스 작성을 위하여 새 파일에서 Objective C class 타입으로 MySqlDB 클랙스를 생성합니다. 이제 MySqlDB.h 파일과 MySqlDB.m 파일을 작성합니다.

테스트를 위하여 연결 및 쿼리등 필요한 메소드만 작성해 보겠습니다. mysql.h 파일을 참고 하시면 MySQL 라이브러리에서 제공하는 많은 함수들을 확인하실 수 있습니다.

1) MySqlDB.h 편집
#import <Cocoa/Cocoa.h>
#import "mysql.h"

@interface MySqlDB : NSObject {

    bool isConnected;
    int rowCount;
    MYSQL mySQL;
    MYSQL *pMySQL;
    MYSQL_RES* pRes;
    MYSQL_ROW Rows;

-(id) initWithServer: (const char*) host
             loginID: (const char*) userid
         loginPasswd: (const char*) passwd
               setDB: (const char*) database;

-(bool) connect : (const char*) host
         loginID: (const char*) userid
     loginPasswd: (const char*) passwd
           setDB: (const char*) database;

-(bool) query :(const char*) str;
-(bool) getRows;
-(bool) getStringData: (int)idx toBuffer: (char *) buff;

-(bool) isConnected;
-(int) rowCount;


2) MySqlDB.m 파일 편집
#import "MySqlDB.h"

@implementation MySqlDB

-(id) initWithServer: (const char*) host
             loginID: (const char*) userid
         loginPasswd: (const char*) passwd
               setDB: (const char*) database
    self = [super init];
    [self connect: host
          loginID: userid
      loginPasswd: passwd
            setDB: database];
    return self;

- (void)dealloc
    [super dealloc];

-(bool) connect : (const char*) host
         loginID: (const char*) userid
     loginPasswd: (const char*) passwd
           setDB: (const char*) database
    isConnected = FALSE;
    pMySQL = mysql_init(&mySQL);
    if(pMySQL == NULL)
        return FALSE;
    pMySQL = mysql_real_connect(&mySQL, host, userid, passwd, database, 0, 0, 0);
    if(pMySQL == NULL)
        return FALSE;
    isConnected = TRUE;
    return TRUE;

-(bool) query: (const char*) str
        return FALSE;
    int ret = mysql_query(pMySQL, str);
    if(ret != 0)
        return FALSE;
    pRes = mysql_store_result(pMySQL);
    rowCount = mysql_num_rows(pRes);
    NSLog(@"rows:%d", rowCount);
    return TRUE;

-(bool) getStringData: (int)idx toBuffer: (char *) buff;
    if(Rows[idx] == NULL)
        return FALSE;
    strcpy(buff, Rows[idx]);
    return TRUE;

-(bool) getRows
    Rows = mysql_fetch_row(pRes);
    if(Rows == NULL)
        return FALSE;

    return TRUE;

-(bool) isConnected
    return isConnected;

-(int) rowCount
    return rowCount;


3) MyTest.m 편집
이제 테스트를 위하여 위에 작성된 클래스를 사용하여 MySQL서버에 접속하여 데이터를 가져오도록  MyTest.m 파일에 소스를 추가해 보겠습니다. 연결시 로그인 정보와 데이터 베이스, 쿼리 내용은 자신의 환경에 맞게 변경해 줍니다.

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

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

    // insert code here...
    MySqlDB* myDB = [[MySqlDB alloc] initWithServer:"localhost"
    if([myDB isConnected] == true)
        if([myDB query :"SELECT * FROM member"])
            char buff1[128];
            char buff2[128];
            [myDB getRows];
            [myDB getStringData: 0 toBuffer: buff1];
            [myDB getStringData: 1 toBuffer: buff2];
            NSLog(@"DATA: id=%s, name=%s", buff1, buff2);
            NSLog(@"Fail to query");
        NSLog(@"Fail to connect.");
    [myDB release]
    [pool release];
    return 0;

3. 빌드옵션 설정 및 라이브러리 등록

MySQL 라이브러리를 사용하기 위해서는 링크시에 라이브러리를 추가하도록 등록하고, 헤더파일을 인크루드하기 위해 위치를 지정해 주어야 합니다.

GCC 옵션에서 -I(인클루드 패스 지정), -L(라이브러리 패스 지정), -l(라이브러리 추가) 옵션을 생각하시면 됩니다.

1) include 패스 설정
빌 드시 헤더파일을 찾을 수 있도록 링크를 설정합니다. 프로젝트 정보창을 오픈합니다. Build 항목에서 "User Header Search Path"에 mysql의 include 패스를 입력합니다. 대부분 /usr/local/mysql에 설치되는데 다른 곳에 설치하신 분들은 그 곳의 패스를 입력합니다.

2. libmysqlclient.a 라이브러리 링크
파 인더에서 해당 디렉토리에 접근하기 힘들기 때문에 터미널에서
 > open /usr/local/mysql/lib 로 파인더를 오픈합니다.

libmysqlclient.a 파일을 드래그 하여 좌측과 같이 Xcode의 Frameworks 그룹으로 가지고 옵니다.

이제 모든 준비가 완료되었습니다. 빌드 후 실행하여 아래와 같은 결과를 확인합니다.

코 코아에서 MySQL 라이브러리를 사용하여 MySQL에 연결하는 방법을 간단히 알아 보았습니다. PostgreSQL이나 다른  C 라이브러리들도 위와 같은 방법으로 코코아에서 사용하실 수 있습니다.

티스토리 블로그 알리미를 작성한 적이 있는데, 설치형 블로그들은 위와 같이 DB에 직접 쿼리하는 방법으로 더욱 쉽고, 다용하고, 정확한 정보를 가져오는 툴을 작성할 수 있을 것 같습니다.

출처 :

'아이폰어플개발정보' 카테고리의 다른 글

[펌] NSURLConnection  (0) 2010.06.21
iPhone 사운드 관련 API  (0) 2010.06.21
[펌] Cocoa 에서 MySQL 라이브러리 사용하기  (0) 2010.06.21
[펌] NSXMLParser 로 RSS 읽어오기  (0) 2010.06.21
iPhone 개발 환경  (0) 2010.06.20
iPhone Software Stack  (0) 2010.06.20
Posted by 오늘마감

댓글을 달아 주세요