I use the following code to draw a subimage
UIImage* subIm = getSubImage( large, rect );
[subIm drawInRect:self.bounds];
where getSubImage
is defined as follows
UIImage* getSubImage(UIImage* uim, CGRect rc){
CGImageRef imref = CGImageCreateWithImageInRect(uim.CGImage, rc);
UIImage* sub = [UIImage imageWithCGImage:imref];
CGImageRelease(imref);
NS开发者_C百科Log(@"subimage retainCount=%d", [sub retainCount]); // is 1
return sub;
}//getSubImage
Is the code correct?
Is it safe to "CGImageRelease" imref?
Has sub "CGImageRetained" imref?
Should I release subIm (I get an error if I do)?
Is subIm contained in the autorelease-pool, and , if so, how do I know this?
In general, can one check if an object is contained in the autorelease pool (for debugging purpose)?
Do Not Call -retainCount
The number returned by retain count is the absolute retain count of the object. There may be many retains in play that you have no control over as they are implementation details of the frameworks. There are always better ways to validate your code's memory management.
Retain counts should only be considered as deltas; if you cause a retain count to increase, you must cause it to be decreased.
Given:
UIImage* getSubImage(UIImage* uim, CGRect rc){
CGImageRef imref = CGImageCreateWithImageInRect(uim.CGImage, rc);
UIImage* sub = [UIImage imageWithCGImage:imref];
CGImageRelease(imref);
NSLog(@"subimage retainCount=%d", [sub retainCount]); // is 1
return sub;
}//getSubImage
imageWithCGImage:
returns an autoreleased object. The retain count is irrelevant in that imageWithCGImage:
might internally be doing any number of things -- caching, etc. -- that might influence the retain count.
get*
is an odd pattern to use in Cocoa programming. You just don't see that much.
I'd suggest something like:
- (UIImage *) subImage: (UIImage *) anImage inRect: (CGRect) aRect
{
CGImageRef imageRef = CGImageCreateWithImageInRect(anImage.CGImage, aRect);
UIImage* subImage = [UIImage imageWithCGImage: imageRef];
CGImageRelease(imageRef);
return subImage;
}
There is a naming convention for memory management. All Cocoa codes follow this rule:
Basic Memory Management Rules
I strongly recommend you read this document and follow the rule too. The naming rule is part of the Cocoa too.
From the reference documentation:
You own any object you create. You “create” an object using a method whose name begins with “alloc” or “new” or contains “copy” (for example, alloc, newObject, or mutableCopy).
You must relinquish ownership of objects you own when you’re finished with them. You relinquish ownership of an object by sending it a release message or an autorelease message (autorelease is discussed in more detail in “Autorelease”). In Cocoa terminology, relinquishing ownership of an object is therefore typically referred to as “releasing” an object.
There is similar rule for C functions of Core Foundation framework. However there is no such autorelease-like things. You have to clarify everything on your documentation if you want to make Objective-C object with C functions.
And this might be helpful to you: imageWithCGImage and memory
SubIm is enrolled in the AutoRelease Pool because this object is in fact created by the class method imageWithCGImage and that the rule is that instances created by class methods should always return autoreleased instances.
The code is correct though I don't understand why your are using the C syntax instead of the Obj-C syntax to define your function
CGImageRelease(imref);
NSLog(@"subimage retainCount=%d", [sub retainCount]); // is 1
return sub;
Because your method doesn't have the keyword alloc, retain, copy..., you have to autorelease the UIImage before returning it. But the factory method of the UIImage already did that for you. Beware that even you autorelease the sub, the retain count is still 1
精彩评论