也说类别Category
转载请注明出处,谢谢。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相关推荐
- iOS进阶之类别(Category)(9)
类别使用场景 见解一 Category的主要作用是为已经存在的类添加方法. Objective-C 中的 Category 就是对装饰模式的一种具体实现.它的主要作用是在不改变原有类的前提下,动态地给 ...
- Magento: 单产品(product)或者当前类别(category)最大和最小价格 Min/Max Product Price in a Category...
1. 当前类别最大最小价格: $minPrice = Mage::getModel('catalog/product')->getCollection()->addStoreFilter( ...
- 类别(Category)的作用(三)---添加非正式协议
在上一篇文章 类别(Category)的作用(二)中,详细说明类别的第二个作用,接下来是类别的第三个作用. 类别作用三:向对象添加非正式协议. 一.概念 显然这个名词是相对于正式协议而言的.什么是正式 ...
- Objective C 类别(Category)与类扩展(Extensions)
一.类别(Category) 类别(Category)是一种可以为现有的类(包括类簇:NSString...,甚至源码无法获得的类)添加新方法的方式无需从现有的类继承子类.类别添加的新方法可以被子类继 ...
- ios 类别(category)
定义 类别(category)是Objective-C语言的新特性,为现有的类添加新方法的方式.局限性:1.无法添加新的实例变量.2.与类本身的方法名称冲突.当名称冲突时,类别具有更高的优先级.作用: ...
- SAP中类型(Type)和类别(Category)详解及其区别
文章目录 一.概述 二.系统示例1-订单 三.系统示例2-凭证 一.概述 类型(Type)和类别(Category)是SAP常见的两个概念,大部分情况下都是一起出现. 如:SD凭证类型和SD凭证类别. ...
- Xcode7创建类别Category
1.File->new file 2.选择Category->next 3.next ->完成
- ios category类别的使用
ios category类别的使用 ios category类别的使用 Objective-C提供了一个非常灵活的类(Class)扩展机制-类别(Category).类别用于对一个已经存在的类添加方法 ...
- java category类_Category(类别)
1.利用Objective-C的动态运行时分配机制,可以为现有的类(自己的或系统的或三方库的)添加新方法,这种为现有的类添加新方法的方式称为类别category,他可以为任何类添加新的方法,包括那些没 ...
最新文章
- UA PHYS515A 电磁理论III 静磁学问题2 标量势方法与向量势方法简介
- JSP页面元素,内置对象及request详解
- linux 64 32 编译支持,在64位linux上编译32位程序 for i386 intel
- qtplaintextedit如何删除内容_YouTube:如何删除油管频道Channel
- 架构名词,涉及的技术
- 《C关键字分析》之typedef与callback
- Costomize Print Output
- GsonFormat的使用 (转)
- matlab retinex,基于Retinex算法视频增强的MATLAB实现
- java根据文件字符换行_java操作txt文本(一):遇到指定字符换行
- python高德地图api调用实例_Python调用高德地图API实现经纬度换算、地图可视化
- 低功耗蓝牙开发入门概念科普
- 宝塔Linux面板配置教程
- 罗永浩二次直播遇冷,用户到底想要什么样的直播 ?
- 对话机器人在瓜子的实践
- 铲雪车(snow) UVA10203 Snow Clearing 题解 优化版
- python if函数用法_python中if条件中的Contains()函数“in”
- UEFI 基础教程 (十六) - ACPI 简单使用
- stm32---DAC数模转换
- 情感AI技术厉害了!看了才知道!!
热门文章
- 2021年5月30日 星期日 晴
- 新酒饮赛道混战升级,果立方和RIO、贝瑞甜心有什么不同?
- three.js创建简单的凹凸贴图
- matlab定步长ode,[转载]matlab ode45 函数传自定义参数用法及定步长ode
- pytorch导出onnx格式模型时,不固定输入输出维度
- 创宇滤镜|API防刷|短信邮件接口防刷|验证码防刷|搜索防刷 - 知道创宇云安全
- 2021-2027全球与中国核磁共振管市场现状及未来发展趋势
- Leet Code OJ 刷题顺序参考
- 用python做动画的代码_Python应用 | 三行代码实现GIF动画
- LaTeX 文章排版 列表环境 表格环境