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

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

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

[java]  view plaincopy

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

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

[java]  view plaincopy

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

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

[java]  view plaincopy

  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");  

[java]  view plaincopy

  1. #import "类名.h"  
  2. @interface 类名(类别名)  
  3. //新方法的声明  
  4. @end  

[java]  view plaincopy

  1. #import "类名类别名.h"  
  2. @interface 类名(类别名)  
  3. //新的实现方法  
  4. @end  

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

[java]  view plaincopy

  1. //  GrayScale.h  
  2. //  XOGameFrame  
  3. //  
  4. //  Created by song on 11-1-12.  
  5. //  Copyright 2011 __MyCompanyName__. All rights reserved.  
  6. //  
  7.  
  8. #import <Foundation/Foundation.h>  
  9.  
  10.  
  11. @interface UIImage (grayscale)  
  12.  
  13. - (UIImage *)convertToGrayscale ;  
  14.  
  15. @end  


[java]  view plaincopy

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

[cpp]  view plaincopy

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


[plain]  view plaincopy

  1. @interface MyClass : NSObject  
  2. - (float)value;  
  3. @end  
  4.  
  5.  
  6. @interface MyClass () { //注意此处:扩展  
  7.    float value;  
  8. }  
  9. - (void)setValue:(float)newValue;  
  10. @end  
  11.  
  12. @implementation MyClass  
  13.  
  14. - (float)value {  
  15.    return value;  
  16. }  
  17.  
  18. - (void)setValue:(float)newValue {  
  19.    value = newValue;  
  20. }  
  21.  
  22. @end  



相关文章
|
JavaScript 前端开发 Java
Objective-C协议(protocol)和委托(delegate)的基本概念(★firecat推荐★)
Objective-C协议(protocol)和委托(delegate)的基本概念(★firecat推荐★)
247 0
|
存储 Java 调度
Objective-C关键字和概念
Objective-C关键字和概念 http://mobile.51cto.com/iphone-402618_all.htm 2013-07-10 11:31 佚名 oschina 字号:T | T 还在面试的时候感觉自己像一只无头苍蝇么?本文为大家整理了一系列iOS面试题,其中包括一些Objective-C的关键字和概念,少编也祝各位马到功成。
1045 0
|
6月前
|
安全 编译器 Swift
IOS开发基础知识: 对比 Swift 和 Objective-C 的优缺点。
IOS开发基础知识: 对比 Swift 和 Objective-C 的优缺点。
394 2
|
4月前
|
开发工具 iOS开发 容器
【Azure Blob】关闭Blob 匿名访问,iOS Objective-C SDK连接Storage Account报错
iOS Objective-C 应用连接Azure Storage时,若不关闭账号的匿名访问,程序能正常运行。但关闭匿名访问后,上传到容器时会出现错误:“Public access is not permitted”。解决方法是将创建容器时的公共访问类型从`AZSContainerPublicAccessTypeContainer`改为`AZSContainerPublicAccessTypeOff`,以确保通过授权请求访问。
【Azure Blob】关闭Blob 匿名访问,iOS Objective-C SDK连接Storage Account报错
|
6月前
|
缓存 开发工具 iOS开发
优化iOS中Objective-C代码调起支付流程的速度
优化iOS中Objective-C代码调起支付流程的速度
104 2