博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
objective-c overview(一)
阅读量:5355 次
发布时间:2019-06-15

本文共 4537 字,大约阅读时间需要 15 分钟。

objective-c(objc)是一种干净的语言。它在c的基础上添加了完整的面向对象特性,却只引入了有限的新语法(相比c++,真是太有限了)。objc还有一个重要特性就是“动态”,可以说objc的动态特性是其他特性(Message,Dynamic Binding, Protocols, Categary, Associative References, Selectors)的基石。它的面向对象特性是动态的,因此比c++和java的更加灵活。

 


 

-消息- 

谈objc一定是从消息开始的。消息的语法也透出了objc作者的美学倾向,即显示地表达你想说的(objc中也不支持运算符重载,函数重载,默认参数等特性也是例证)。消息的定义是这样的:

- (void)setWidth:(float)width height:(float)height; setWidth既是函数名也是对第一个参数的说明, height是对第二个参数的说明。因此,objc的消息名就是每个参数说明的罗列。

消息的调用:

[obj setWidth:20.0 height:30.0];

消息和通常所说的方法不同之处在于,消息的绑定是在运行期,而方法的绑定是在编译期。因此,以下调用:

[nil setWidth:20.0 height:30.0]; 是合法的但没有什么效果,类似于一个空语句。

更进一步,由于objc的动态实现,可以在运行期判断一个对象是否有实现该消息,并决定是否向该对象发送该消息:

- (id)negotiate{    if ([someOtherObject respondsTo:@selector(negotiate)])        return [someOtherObject negotiate];    return self;} 

 

-id-

objc的任何对象都可以是id类型,它有点像c的void*。由于objc有完备的动态类型系统,从任何一个对象指针出发都能找到和该对象相关的方法、属性定义信息,以及类继承关系,接口定义等。因此定义一个对象时,它是什么类型已经不那么重要。而给出确切的类型,有助于编译阶段做更多的类型检查。c++的动态部分就是它的虚函数表,objc将其扩展为完全的类信息。因此,objc的所有消息都是“虚函数”。

 


 

-类定义-

因此,为了获得这种动态能力,所有的objc类都继承至NSObject。

@interface ClassName : ItsSuperclass{    instance variable declarations}method declarations@end

其中类方法前为’+‘号, 对象方法前为’-‘号:

+ alloc;- (void)display;- (void)setWidth:(float)width height:(float)height; 如果需要引用其他类,可以用前置声明:
@class Rectangle, Circle;
也可以包含头文件:
#import "Rectangle.h"

类实现:

#import “ClassName.h"@implementation ClassNamemethod definitions@end+ (id) alloc{   ...}- (BOOL)isFilled{   ...}

类似于c++,objc也提供了关键字,以限定成员变量的可视范围,它们是:@private,@protected,@public以及@package。由于成员变量都是通过setter\getter访问的,因此对于外部代码,成员变量的访问权限是由@propertity的属性决定的(更多信息可以baidu得到)。

objc还提供了两个关键字:self和super,分别用于引用本类和父类的定义(属性、消息)。

 


 

-创建对象-

相对于c++的构造函数,objc对象的分配和创建都需要显式调用:

id anObject = [[Rectanle alloc] init];

对于init的实现,有如下惯例:

  • 返回类型必须是id
  • 每个类最好都有一个具名初始化方法(designated initializer),该初始化方法有者最全的参数声明,该类的其他initializer都是调用它实现的。
  • 每个类的designated initializer都必须调用父类的designated initializer。
  • 对于成员变量的付值,直接使用‘=’,而不是getter和setter方法。
  • 返回值必须是self或者nil。
  • 调用父类的initializer时,必须将其返回值付给self,因为父类的initializer可能返回不同的对象。
  • 本类的initializer初始化本类定义的成员变量,父类的定义的成员变量交友父类的initializer初始化。
  • 当初始化失败时,可以发送release,释放self(见第二个例子)。
// an class initializer succeed inherits from NSObject - (id)init {    // Assign self to value returned by super's designated initializer    // Designated initializer for NSObject is init    self = [super init];    if (self) {        creationDate = [[NSDate alloc]init];    }    return self;}
- (id)initWithURL:(NSURL *)aURL error:(NSError **)errorPtr {        self = [supper init];    if (self) {                NSData *data = [[NSData alloc] initWithContentsOfURL:aURL options:NSUncachedRead error:errorPtr]; if (data == nil) { // In this case the error object is created in the NSData initializer  [self release]; return nil; } ... } }

 

-Protocols-  协议是一类方法的集合。几个类,它们可能分属于不同的继承树,但却可以实现相同的协议。 有时,我们并不知道该对象的类型,但却知道它实现了什么协议,就可以向它发送协议规定的消息。 协议的定义:
@protocol MyXMLSupport- initFromXMLRepresentation:(NSXMLElement *)XMLElement;- (NSXMLElement *)XMLRepresentation;@end 以上协议中规定的方法都是必须实现的。实际上程序可以用@required 和 @optional限定方法是否是必须的或可选的:
@protocol MyXMLSupport@required- initFromXMLRepresentation:(NSXMLElement *)XMLElement;@optional- (NSXMLElement *)XMLRepresentation;@end

非正式协议:

非正式协议是用category定义的。category本意是用来对类进行动态扩展的。当你没有该类的定义,甚至只有该类的二进制文件的时候,你想为该类添加方法定义。因此这些方法可以实现在独立的*.h和*.m文件中。

非正式协议通常声明为NSObject的categary:

@interface NSObject (MyXMLSupport)- initFromXMLRepresentation:(NSXMLElement *)XMLElement;- (NSXMLElement *)XMLRepresentation;@end

由于所有的类都是继承至NSObject,因此上述定义将扩散到所有的类中,这也是危险的。

作为非正式协议,缺少语言层面的支持,既没有编译期的类型检查,也无法在运行期判断一个对象是否遵循一个非正式协议(发送conformsToProtocol:消息)。

非正式协议所有方法都是optional的,在有些情况下当所有方法都是可选时,也可以使用非正式协议,但更推荐使用正式协议加optional关键字。

总之,尽量使用正式协议。

 

协议对象:

我们可以使用@protocol()关键字获取协议对象:

Protocol *myXMLSupportProtocol = @protocol(MyXMLSupport);

上述表达式,编译器为我们创建了一个名为myXMLSupportProtocol的协议对象。和类不同,类名就时一个类对象。

如果一个类实现了协议,编译器也会创建一个协议对象,当然我们看不到这个对象。

 

   Adopting a Protocol:

//class adopt protocols@interface ClassName : ItsSuperclass < protocol list >//and categories adopt protocols in the same way:@interface ClassName ( CategoryName ) < protocol list > //a class adopt protocols and declare no other methods @interface Formatter : NSObject < Formatting, Prettifying > @end Conforming to a Protocol:
if (  ! [receiver conformsToProtocol:@protocol(MyXMLSupport)]  ) {    // Object does not conform to MyXMLSupport protocol    // If you are expecting receiver to implement methods declared in the    // MyXMLSupport protocol, this is probably an error} Type Checking:
- (id 
)formattingService;id
anObject;
 

转载于:https://www.cnblogs.com/mjohh/p/4946938.html

你可能感兴趣的文章
直播技术细节3
查看>>
《分布式服务架构:原理、设计于实战》总结
查看>>
java中new一个对象和对象=null有什么区别
查看>>
字母和数字键的键码值(keyCode)
查看>>
IE8调用window.open导出EXCEL文件题目
查看>>
Spring mvc初学
查看>>
VTKMY 3.3 VS 2010 Configuration 配置
查看>>
01_1_准备ibatis环境
查看>>
windows中修改catalina.sh上传到linux执行报错This file is needed to run this program解决
查看>>
JavaScript中的BOM和DOM
查看>>
360浏览器兼容模式 不能$.post (不是a 连接 onclick的问题!!)
查看>>
spring注入Properties
查看>>
jmeter(五)创建web测试计划
查看>>
python基本数据类型
查看>>
1305: [CQOI2009]dance跳舞 - BZOJ
查看>>
将html代码中的大写标签转换成小写标签
查看>>
jmeter多线程组间的参数传递
查看>>
零散笔记
查看>>
MaiN
查看>>
[Python学习] 简单网络爬虫抓取博客文章及思想介绍
查看>>