objective-c overview(上)

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;
}<Objective-C Runtime Guider.pdf>


-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 ClassName
method 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,因此上述定义将扩散到所有的类中,这也是危险的。

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

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

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

时间: 2024-08-02 00:15:59

objective-c overview(上)的相关文章

Chrome开发者工具详解(3):Timeline面板

Timeline面板 Timeline面板是整个面板里面最复杂的一个面板,涉及的东西比较多.可以利用这个面板来记录和分析网页运行过程中的所有活动行为信息. 你可以充分利用这个面板来分析你的网页的程序性能问题. 概述 下图是从Google官方网站中介绍Timeline面板的图贴到这里,该面板主要包括4大块窗格(Pane): Controls 录制开关和控制录制过程中需要记录哪些信息. Overview 网页性能的概要信息. Flame Chart CPU堆栈轨迹的可视化图表(火焰图).在图表里面有

Timeline

Timeline面板 Chrome开发者工具详解(3)-Timeline面板 注: 这一篇主要讲解面板Timeline,参考了Google的相关文档,主要用于公司内部技术分享.. 更新时间:2016-10-24 Timeline面板 Timeline面板是整个面板里面最复杂的一个面板,涉及的东西比较多.可以利用这个面板来记录和分析网页运行过程中的所有活动行为信息.你可以充分利用这个面板来分析你的网页的程序性能问题. 概述 下图是从Google官方网站中介绍Timeline面板的图贴到这里,该面板

Chrome 开发者工具详解(2):Network 面板

面板上包含了Elements面板.Console面板.Sources面板.Network面板. Timeline面板.Profiles面板.Application面板.Security面板.Audits面板这些功能面板. 这些按钮的功能点如下: Elements:查找网页源代码HTML中的任一元素,手动修改任一元素的属性和样式且能实时在浏览器里面得到反馈. Console:记录开发者开发过程中的日志信息,且可以作为与JS进行交互的命令行Shell. Sources:断点调试JS. Network

10大iOS开发者最喜爱的类库

该10大iOS开发者最喜爱的库由“iOS辅导团队”成员Marcelo Fabri组织投票选举而得,参与者包括开发者团队,iOS辅导团队以及行业嘉宾.每个团队都要根据以下规则选出五个最好的库:1)不能投自己写的库:2)排除大的架构,比如游戏类架构:3)排除不在设备上运行的库,例如CocoaPods或者Rack::CoreData也排除在外. 最终评选出了如下10大iOS开发者最喜爱的库: 1)SSToolkit Sam Soffes简直就是一个Objective-C天才,SSToolkit就是个例

Dev-如何查找资料

Dev国内的资料比较少,但是国外的资料比较少,Google在国内不能使用是难题. 这就要感谢Google访问助手. 可以安装Google访问助手,然后将要查找的资料翻译成简易的英文进行查找. 便可以得到好多资料. 官方网址: https://documentation.devexpress.com/#GeneralInformation/CustomDocument3930 这个网址可以查看控件的属性. http://demos.devexpress.com/MVCxNavigationAndL

Project Management Process

Project Management ProcessDescription .......................................................................................................................................................................................1STAGE/STEP/TASK SUMMARY LIST

总结分享十大iOS开发者最喜爱的库

该10大iOS开发者最喜爱的库由"iOS辅导团队"成员Marcelo Fabri组织投票选举而得,参与者包括开发者团队,iOS辅导团队以及行业嘉宾.每个团队都要根据以下规则选出五个最好的库:1)不能投自己写的库;2)排除大的架构,比如游戏类架构;3)排除不在设备上运行的库,例如CocoaPods或者Rack::CoreData也排除在外. 最终评选出了如下10大iOS开发者最喜爱的库: 1)SSToolkit Sam Soffes简直就是一个Objective-C天才,SSToolki

Mobile first! Wijmo 5 + Ionic Framework之:费用跟踪 App

?? 费用跟踪应用采用了Wijmo5和Ionic Framework创建,目的是构建一个hybird app. 我们基于<Mobile first! Wijmo 5 + Ionic Framework之:Hello World!>的环境,将在本教程中完成费用跟踪App的构建.下面的代码结构是本教程完成要达到的效果,请预先创建好文件和目录. www/ --> 工程根目录 index.html --> app 布局文件 (主HTML文件) css/ --> css 目录 js/

生产线平衡问题的+Leapms解法

生产线平衡问题 (The Assembly Line Balancing Problem) 生产线又叫做组装生产线, 是把产品的工艺做串行生产安排的流水生产线.一个产品的组装需要不同的工序来完成,且工序之间有先后次序要求. 下表是Jackson, J. R. . (1956)给出一个产品工序的装配次序要求: 工序 执行时长 紧前工序 1 6 -- 2 2 1 3 5 1 4 7 1 5 1 1 6 2 2 7 3 3,4,5 8 6 6 9 5 7 10 5 8 11 4 10,9 上表也可以用

chrome F12_Network 开发者工具详解

本文为学习chrome F12_Network的一点记录,如有不妥之处请各位大神指点,谢谢! 开发者工具面板 最常用的前四个功能模块如下: Elements:查找网页源代码HTML中的任一元素,手动修改任一元素的属性和样式且能实时在浏览器里面得到反馈. Console:录开发者开发过程中的日志信息,且可以作为与JS进行交互的命令行Shell. Sources:断点调试JS. Network:从发起网页页面请求Request后分析HTTP请求后得到的各个请求资源信息(包括状态.资源类型.大小.所用