读书人

IOS4 note 13 (四)

发布时间: 2012-06-26 10:04:13 作者: rapoo

IOS4 note 13 (4)

Memory Management of Pointer-to-Void Context Info

A number of Cocoa methods take an optional parameter typed as void*, and often?called context.?An id is a universal object type; void* is just a C pointer. This means that Cocoa won’t?treat this value as an object. So the use of the void* type is a clue to you that Cocoa?won’t do any memory management on this value.?

As an example, ?I’ll use beginAnimations:context:. You call ?this on a UIView before?changing one or more of its property values, such as its size, position, or opacity, to?make ?those changes appear animated.

A better approach is to make these context objects persistent, as instance variables or?globals, and manage their memory as you would any persistent pointer. A context?object will thus persist even after it is no longer needed, but it won’t actually leak,?provided you release it before you yourself (the managing object) go out of existence.

Here’s a complete example:

static id g_animcontext = nil;

- (void) animate {

? ? // set up context info pointer with memory management

? ? [g_animcontext release];

? ? g_animcontext = [NSDictionary dictionaryWithObject: @"object" forKey: @"key"];

? ? [g_animcontext retain];

? ? // prepare animation

? ? [UIView beginAnimations:@"shrinkImage" context:g_animcontext];

? ? [UIView setAnimationDelegate:self];

? ? [UIView setAnimationDidStopSelector:@selector(animationDidStop:finished:context:)];

? ? [imv setAlpha: 0];

? ? // request animation to start

? ? [UIView commitAnimations];

}

?

- (void) animationDidStop:(NSString*)anim

? ? ? ? ? ? ? ? ?? ??finished:(NSNumber *)f context:(void *)c {

? ? NSDictionary* d = c; // cast back to dictionary, use as desired

? ? // no memory management for context info here

? ? // ...

}

?

- (void)dealloc {

? ? [g_animcontext release];

? ? // ... other releases and so forth ...

? ? [super dealloc];

}

?

Considerations of this sort do not apply to parameters that are typed as objects. For?instance, when you call postNotificationName:object:userInfo:, the userInfo is typed?as an NSDictionary and is retained for you (and released after the notification is posted);?its memory management is not your concern.

?

Memory Management of C Struct Pointers

A value obtained through a C function that is a pointer to a struct (its type name will?usually ?end ?in “Ref”) is a kind of object, even though it isn’t a full-fledged Cocoa?Objective-C object, and it must be managed in much the same way as a Cocoa object. The rule here is that if you obtained such an object through a function whose name?contains the word Create or Copy, you are responsible for releasing it. In the case of a?Core Foundation object (its type name begins with CF), you’ll release it with the?CFRelease function; other object creation functions are paired with their own object?release functions.

An ?Objective-C ?object ?can ?be ?sent ?messages ?even ?if ?it ?is ?nil. ?But?CFRelease ?cannot ?take ?a NULL ?argument. Be ?sure ?that ?a pointer-to-struct variable is not NULL before releasing it.

The matter is not a complicated one; it’s much simpler than memory management of?Cocoa objects, and the documentation will usually give you a hint about your memory?management ?responsibilities. As an example, here (without further explanation) is?some actual code from one of my apps, strongly modeled on Apple’s own example?code, in which I set up a base pattern color space (for drawing with a pattern):

- (void) addPattern: (CGContextRef) context color: (CGColorRef) incolor {

? ? CGColorSpaceRef baseSpace;

? ? CGColorSpaceRef patternSpace;

? ? baseSpace = CGColorSpaceCreateDeviceRGB ();

? ? patternSpace = CGColorSpaceCreatePattern (baseSpace);

? ? CGContextSetFillColorSpace (context, patternSpace);

? ? CGColorSpaceRelease (patternSpace);

? ? CGColorSpaceRelease (baseSpace);

? ? // ...

}

Similarly, you can retain a Core Foundation object, if you are afraid that it might go?out of existence while you still need it, with the CFRetain function, and you are then,?once again, responsible for releasing it with the CFRelease function.

When a Core Foundation object type is toll-free bridged with a Cocoa object type, it?makes no difference whether you use Core Foundation memory management or Cocoa?memory management. For example, ?if you obtain a CFStringRef and assign ?it to an?NSString variable, sending release to it through the NSString variable is just as good?as calling CFRelease on it.?

读书人网 >操作系统

热点推荐