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. 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值