天天看点

Objective-C类别(category)和扩展(Extension)的基本概念

category 是Objective-C 里面最常用到的功能之一。category 可以为已经存在的类增加方法,而不需要增加一个子类。而且,我们可以在不知道某个类内部实现的情况下,为该类增加方法。如果我们想增加某个框架(framework)中的类的方法,category 就非常有效。比如,如果想在NSString 上增加一个方法来判断它是否是有效的 URL,那么就可以这样做: http://blog.csdn.net/yhawaii/article/details/6992094 [java] view plain copy

  1. @interface NSString (hello)  
  2. - (BOOL) isURL;  
  3. @end  

是不是觉得与类的定义非常像,确实,就是category 没有父类,而且后面要跟括号里面写category 的名字,名字可以随便取。下面是刚刚 isURL 的实现:

  1. @implementation NSString(hello)  
  2. - (BOOL) isURL{  
  3.        if( [self hasPrefix:@"http://"] )  
  4.            return YES;  
  5.        else  
  6.            return NO;  
  7. }  

现在就可以在任何NSString类对象上调用这个方法了。下面是一个调用的例子:

  1. NSString* str1 = @"http://www.blog.csdn.net/iukey";  
  2. NSString* str2 = @"刘伟Lewis";  
  3. if([str1 isURL])  
  4.    NSLog(@"str1 is a URL");  
  5. if([str2 isURL])  
  6.    NSLog(@"str2 is a URL");  
  1. #import "类名.h"  
  2. @interface 类名(类别名)  
  3. //新方法的声明  
  1. #import "类名类别名.h"  
  2. //新的实现方法   

注意:类别并不能为类声明新的实例变量,他只包含方法。然而在类作用域内所有实例变量,都能被这些类别访问。他们包括为类声明的所有的实例变量,甚至那些被@private 修饰的变量。可以为一个类添加多个类别,但每个类别名必须不同,而且每个类别都必须声明并实现一套不同的方法。

  1. //  GrayScale.h  
  2. //  XOGameFrame  
  3. //  
  4. //  Created by song on 11-1-12.  
  5. //  Copyright 2011 __MyCompanyName__. All rights reserved.  
  6. #import <Foundation/Foundation.h>  
  7. @interface UIImage (grayscale)  
  8. - (UIImage *)convertToGrayscale ;  
  1. //  GrayScale.m  
  2. #import "GrayScale.h"  
  3. @implementation UIImage (grayscale)  
  4. typedef enum {  
  5.     ALPHA = 0,  
  6.     BLUE = 1,  
  7.     GREEN = 2,  
  8.     RED = 3  
  9. } PIXELS;  
  10. - (UIImage *)convertToGrayscale {  
  11.     CGSize size = [self size];  
  12.     int width = size.width;  
  13.     int height = size.height;  
  14.     // the pixels will be painted to this array  
  15.     uint32_t *pixels = (uint32_t *) malloc(width * height * sizeof(uint32_t));  
  16.     // clear the pixels so any transparency is preserved  
  17.     memset(pixels, 0, width * height * sizeof(uint32_t));  
  18.     CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();  
  19.     // create a context with RGBA pixels  
  20.     CGContextRef context = CGBitmapContextCreate(pixels, width, height, 8, width * sizeof(uint32_t), colorSpace,   
  21.                                                  kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedLast);  
  22.     // paint the bitmap to our context which will fill in the pixels array  
  23.     CGContextDrawImage(context, CGRectMake(0, 0, width, height), [self CGImage]);  
  24.     for(int y = 0; y < height; y++) {  
  25.         for(int x = 0; x < width; x++) {  
  26.             uint8_t *rgbaPixel = (uint8_t *) &pixels[y * width + x];  
  27.             // convert to grayscale using recommended method:  http://en.wikipedia.org/wiki/Grayscale#Converting_color_to_grayscale
  28.             uint32_t gray = 0.3 * rgbaPixel[RED] + 0.59 * rgbaPixel[GREEN] + 0.11 * rgbaPixel[BLUE];  
  29.             // set the pixels to gray  
  30.             rgbaPixel[RED] = gray;  
  31.             rgbaPixel[GREEN] = gray;  
  32.             rgbaPixel[BLUE] = gray;  
  33.         }  
  34.     }  
  35.     // create a new CGImageRef from our context with the modified pixels  
  36.     CGImageRef image = CGBitmapContextCreateImage(context);  
  37.     // we're done with the context, color space, and pixels  
  38.     CGContextRelease(context);  
  39.     CGColorSpaceRelease(colorSpace);  
  40.     free(pixels);  
  41.     // make a new UIImage to return  
  42.     UIImage *resultUIImage = [UIImage imageWithCGImage:image];  
  43.     // we're done with image now too  
  44.     CGImageRelease(image);  
  45.     return resultUIImage;  

[cpp]

  1. /*
  2. 定义分类的过程大致可分为以下几个步骤:
  3.     第一步、创建一个带有接口的新文件,即创建已有类
  4.     第二步、在新文件中添加需要扩展的方法及方法的实现,即需要添加的分类
  5.  */  
  6. //NSString 表示将要添加分类的类名称,该类必须是已存在的。  
  7. //CamelCase 是为类添加的方法名称。  
  8. //只能添加方法,不能添加变量。  
  9. //头文件命名惯例:ClassName+CategoryName.h  
  10. @interface NSString (CamelCase)  
  11. -(NSString*) camelCaseString;  
  12. @implementation NSString (CamelCase)  
  13. -(NSString*) camelCaseString  
  14. {  
  15.     //调用NSString的内部方法获取驼峰字符串。  
  16.     //self指向被添加分类的类。  
  17.     NSString *castr = [self capitalizedString];  
  18.     //创建数组来过滤掉空格, 通过分隔符对字符进行组合。  
  19.     NSArray *array = [castr componentsSeparatedByCharactersInSet:  
  20.                       [NSCharacterSet whitespaceCharacterSet]];  
  21.     //把数组的字符输出  
  22.     NSString *output = @"";  
  23.     for(NSString *word in array)  
  24.     {  
  25.         output = [output stringByAppendingString:word];  
  26.     return output;  
  27. int main (int argc, const char * argv[])  
  28.     NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];  
  29.     NSString *str = @"My name is bill.";  
  30.     NSLog(@"%@", str);  
  31.     str = [str camelCaseString];  
  32.     [pool drain];  
  33.     return 0;  

[plain]

  1. @interface MyClass : NSObject  
  2. - (float)value;  
  3. @interface MyClass () { //注意此处:扩展  
  4.     float value;  
  5. - (void)setValue:(float)newValue;  
  6. @implementation MyClass  
  7. - (float)value {  
  8.     return value;  
  9. - (void)setValue:(float)newValue {  
  10.     value = newValue;  
  11. @end