转载请注明出处,谢谢。http://blog.csdn.net/cloosen/article/category/1191708

该文章会不定时更新,因为毕竟一次把他写全有点难,有的东西忘了写了什么的,如果想起来会补充进去,如果大家有什么疑问可以留言,如果我了解会不定时回答的,3Q.

题外话:今天终于转正了,签了一份3年有违约金的合同,之前公司VP面我得时候说过,公司招过无数牛人,并且公司会给每个人充裕的时间学习,有些人学习了,有些人荒芜了,三年后有些人变成了行业巨牛,有些人泯然众人了。觉得自己真该努力了,要不然三年之后就不知道什么样子了。

言归正传,也说说Catagory这个东西,这次学聪明了,不像上次写属性的时候写完了才发现苹果的文档,还好有很多东西跟他不一样,要不然不就白写了?有兴趣的童鞋可以先看看苹果关于类别的文档:http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjectiveC/Chapters/ocCategories.html#//apple_ref/doc/uid/TP30001163-CH20-SW2。当然了如果你觉得英文看着不爽,你可以去搜搜,有人把他翻译成了汉语。

类别(Category),是objective-C所特有的一种设计模式,它用来对现有的类进行方法和属性的扩充和优化,即使在完全不知道现有类的代码的情况下。

最正常的类别写法如下。这个各个blog,各种文档,各种书几乎都是这么写的,因为苹果文档就是这么写的,哈哈。

.h文件

#import <UIKit/UIKit.h>@interface UIButton (Test)- (void)myMethod;@end

.m文件

#import "UIButton+Test.h"@implementation UIButton (Test)- (void)myMethod
{NSLog(@"myMethod is success~~~");
}@end

其他类

[button myMethod];

这么写没啥好说的,规定的,你用UIButton的实例,他已经包含了该方法。

类别和继承十分的相似,都是对其他类进行扩展,但是他们有两点不同,1是类别中无法加入实例变量,2是类别中不到万不得已千万别重写主类的方法。

先说说第一点类别中无法加入实例变量,但是你可以加入属性。因为没有实例变量,所以你也无法用@synthesize,因为类无法给你自动生成set和get方法,所以我自己写了set和get方法,之前写了个小demo,代码如下:

.h文件

#import <UIKit/UIKit.h>@interface UIButton (Test)
{//什么也不能加,不信你试试
}@property(nonatomic,retain) NSString *myTitle;- (void)myMethod;@end

.m文件

#import "UIButton+Test.h"@implementation UIButton (Test)//不能写@synthesize- (NSString *)myTitle
{return @"hahahaha,you can get~~";
}- (void)setMyTitle:(NSString *)inputTitle
{NSLog(@"you want set title :%@",inputTitle);
}- (void)myMethod
{NSLog(@"myMethod is success~~~");
}@end

其他类

    button.myTitle=@"have a look";NSString *abab = button.myTitle;NSLog(@"%@",abab);[button myMethod];

可以看出控制台输出结果

可以看到,我们写的set,get方法居然被调用到了,所以我觉得自己实现属性的功能完全靠谱,但是因为没有实例变量,无法存储,所以写得set,get并没起到什么大作用,因为实例变量的最终作用有一点就是帮助你完成 set和 get方法。实例变量的作用就是保存一些我们想要保存的值,用于过度,所以我们很容易就想出可以用 static,搞一个全局变量来替代实例变量,从辅助我们完成方法的编写,这样我们就用了联合存储模式(以后的 blog会讲)模拟了添加实例变量的效果,代码如下:

.m文件

#import "UIButton+Test.h"
#import <objc/runtime.h>static char MYTITLE;@implementation UIAlertView (Block)@dynamic myTitle;- (void)setMyTitle:(NSString *)myTitle
{
objc_setAssociatedObject(self, &MYTITLE, myTitle, OBJC_ASSOCIATION_COPY_NONATOMIC);
}- (NSString *)myTitle
{
return objc_getAssociatedObject(self, &MYTITLE);
}

其中方法可以参考苹果的文档:http://developer.apple.com/library/mac/#documentation/cocoa/conceptual/ObjectiveC/Chapters/ocAssociativeReferences.html
提示一下,这个函数API在ios3.1以上才有的,不是说这是联合存储模式实现的么,其实底层用的是NSMapXXX实现的,在ios3.1的时候给封装成了API而已,底层实现将在讲联合存储的时候详细讨论.

然后再说下第2点类别中不到万不得已千万别重写主类的方法
        override这个词大家都再熟悉不过,oop中子类对父类的方法进行重写,子类的该方法也能用,父类的该方法也能用,体现了多态特性,类别中也可以重写主类的方法,但是此重写非彼重写,我想用replace比较合适,就是将主类的该方法完全替换掉了,你再也获得不到主类的此方法,一般多此继承的类第一句都会是[super XXXXX],没错,你无法调用主类的父类做的事情了,可以说你少做了很多事情,经常会出现一些很诡异的bug。所以说万不得已千万别重写主类的方法,但是什么时候要重写呢,就是当主类该方法有问题的时候,这样我们重写他,将他原来的有问题代码replace掉,当时调试UIPageViewController的时候有一个苹果内部相关的什么类来的忘了,控制台说XX方法有问题,然后被我重写了之后好了.

什么时候用类别,什么时候用继承,确实是一个很让人纠结的事情,没有必须用类别的情况,也没有必须用继承的情况,按书上说的,如果需要把新的实例变量添加到类中,那么继承是优先选择.类别可以用联合存储的模式来模拟实例变量,但是需要以性能为代价;对复杂的类,进行子类化十分困难,类别可以用来替代继承,一般向基类中添加类别比较好,其所有的子类都能用.
        你可以对一个类进行无限次扩展,即写无数个类别,但是有一点是要保证得,你的类别的名字不能重复

类别还有个好处就是可以分布在多个文件中,这样无论在开发还是维护中都非常好。类别之前还被用作创建非正式协议,后来被protocol的@optional给替代了,现在几乎没有人用类别来创建非正式协议了。再后来就有了类的扩展(Class Extensions),它主要用来:1.做函数的前置声明,2.用于定义私有属性,可参见之前的blog:http://blog.csdn.net/cloosen/article/details/7796398。当Extensions中写了没有被实现的方法时,编译器会报warning,而Category中写了没有被实现的方法时,编译器会当成非正式协议,从而什么都不会做.

最后说一下,其实类别也可以实现protocol,这个我用的比较少,以后搞明白了在加上吧.
协议可以放在类别的.h文件中

@interface UIButton (Test)<UIAlertViewDelegate>

也可以放在类别的.m文件中用Extensions隐藏起来.

以上就是我所了解和掌握的一些关于类别的知识,现在无论是重构还是构建library,用继承还是很多的,因为对类别了解不够深,估计以后在工作中会积累更多了,书上说类别还是要优于继承的,这篇文章也会随着我慢慢了解而不断更新的.
转载请注明出处,谢谢.http://blog.csdn.net/cloosen/article/category/1191708
------------------------by 郭大虎

也说类别Category相关推荐

  1. iOS进阶之类别(Category)(9)

    类别使用场景 见解一 Category的主要作用是为已经存在的类添加方法. Objective-C 中的 Category 就是对装饰模式的一种具体实现.它的主要作用是在不改变原有类的前提下,动态地给 ...

  2. Magento: 单产品(product)或者当前类别(category)最大和最小价格 Min/Max Product Price in a Category...

    1. 当前类别最大最小价格: $minPrice = Mage::getModel('catalog/product')->getCollection()->addStoreFilter( ...

  3. 类别(Category)的作用(三)---添加非正式协议

    在上一篇文章 类别(Category)的作用(二)中,详细说明类别的第二个作用,接下来是类别的第三个作用. 类别作用三:向对象添加非正式协议. 一.概念 显然这个名词是相对于正式协议而言的.什么是正式 ...

  4. Objective C 类别(Category)与类扩展(Extensions)

    一.类别(Category) 类别(Category)是一种可以为现有的类(包括类簇:NSString...,甚至源码无法获得的类)添加新方法的方式无需从现有的类继承子类.类别添加的新方法可以被子类继 ...

  5. ios 类别(category)

    定义 类别(category)是Objective-C语言的新特性,为现有的类添加新方法的方式.局限性:1.无法添加新的实例变量.2.与类本身的方法名称冲突.当名称冲突时,类别具有更高的优先级.作用: ...

  6. SAP中类型(Type)和类别(Category)详解及其区别

    文章目录 一.概述 二.系统示例1-订单 三.系统示例2-凭证 一.概述 类型(Type)和类别(Category)是SAP常见的两个概念,大部分情况下都是一起出现. 如:SD凭证类型和SD凭证类别. ...

  7. Xcode7创建类别Category

    1.File->new file 2.选择Category->next 3.next ->完成

  8. ios category类别的使用

    ios category类别的使用 ios category类别的使用 Objective-C提供了一个非常灵活的类(Class)扩展机制-类别(Category).类别用于对一个已经存在的类添加方法 ...

  9. java category类_Category(类别)

    1.利用Objective-C的动态运行时分配机制,可以为现有的类(自己的或系统的或三方库的)添加新方法,这种为现有的类添加新方法的方式称为类别category,他可以为任何类添加新的方法,包括那些没 ...

最新文章

  1. UA PHYS515A 电磁理论III 静磁学问题2 标量势方法与向量势方法简介
  2. JSP页面元素,内置对象及request详解
  3. linux 64 32 编译支持,在64位linux上编译32位程序 for i386 intel
  4. qtplaintextedit如何删除内容_YouTube:如何删除油管频道Channel
  5. 架构名词,涉及的技术
  6. 《C关键字分析》之typedef与callback
  7. Costomize Print Output
  8. GsonFormat的使用 (转)
  9. matlab retinex,基于Retinex算法视频增强的MATLAB实现
  10. java根据文件字符换行_java操作txt文本(一):遇到指定字符换行
  11. python高德地图api调用实例_Python调用高德地图API实现经纬度换算、地图可视化
  12. 低功耗蓝牙开发入门概念科普
  13. 宝塔Linux面板配置教程
  14. 罗永浩二次直播遇冷,用户到底想要什么样的直播 ?
  15. 对话机器人在瓜子的实践
  16. 铲雪车(snow) UVA10203 Snow Clearing 题解 优化版
  17. python if函数用法_python中if条件中的Contains()函数“in”
  18. UEFI 基础教程 (十六) - ACPI 简单使用
  19. stm32---DAC数模转换
  20. 情感AI技术厉害了!看了才知道!!

热门文章

  1. 2021年5月30日 星期日 晴
  2. 新酒饮赛道混战升级,果立方和RIO、贝瑞甜心有什么不同?
  3. three.js创建简单的凹凸贴图
  4. matlab定步长ode,[转载]matlab ode45 函数传自定义参数用法及定步长ode
  5. pytorch导出onnx格式模型时,不固定输入输出维度
  6. 创宇滤镜|API防刷|短信邮件接口防刷|验证码防刷|搜索防刷 - 知道创宇云安全
  7. 2021-2027全球与中国核磁共振管市场现状及未来发展趋势
  8. Leet Code OJ 刷题顺序参考
  9. 用python做动画的代码_Python应用 | 三行代码实现GIF动画
  10. LaTeX 文章排版 列表环境 表格环境