当前位置首页 > 百科> 正文

object-c

2019-08-24 03:14:43 百科
object-c

object-c

Object-C通常写作Objective-C或者Obj-C或OC,是根据C语言所衍生出来的语言,继承了C语言的特性,是扩充C的面向对象程式语言。它主要使用于Mac OS X和GNUstep这两个使用OpenStep标準的系统,而在NeXTSTEP和OpenStep中它更是基本语言。Objective-C可以在gcc运作的系统写和编译,因为gcc含Objective-C的编译器。在MAC OS X系统下,运用苹果提供的SDK等开发工具包,可以用来做IOS开发,开发后的程式在Iphone虚拟机中进行测试,运用的主要语言为Object-c。与C#类似。Object-c仅支持单一父类继承,不支持多重继承。

基本介绍

  • 中文名:Objective-C
  • 别称:Objective-C
  • 发明:布莱德·确斯
  • 公司:Stepstone

发展历史

二十世纪80年代初布莱德·确斯(Brad Cox)在其公司Stepstone发明Objective-C。他对软体设计和编程里的真实可用度问题十分关心。 Objective-C最主要的描述是他1986年出版的Object Oriented Programming: An Evolutionary Approach. Addison Wesley. ISBN 0-201-54834-8.

优点及缺点

Objective-C是非常“实际”的语言。它使用一个用C写成、很小的运行库,只会令应用程式的大小增加很小,和大部分OO系统使用极大的VM执行时间会取代了整个系统的运作相反,ObjC写成的程式通常不会比其原始码大很多。而其库函式(通常没附在软体发行本)亦和Smalltalk系统要使用极大的记忆体来开启一个视窗的情况相反。 Objective-C的最初版本并不支持垃圾回收。在当时这是争论的焦点之一,很多人考虑到Smalltalk回收时有漫长的“死亡时间”,令整个系统失去作用。Objective-C为避免此问题才不拥有这个功能。虽然某些第三方版本已加入这个功能(尤是GNUstep),Apple在其Mac OS X 10.3中仍未引入这个功能。 另一个问题是ObjC不包括命名空间机制(namespace mechanism)。取而代之的是程式设计师必须在其类别名称加上前缀,时常引致冲突。在2004年,在Cocoa编程环境中,所有Mac OS X类别和函式均有“NS”作为前缀,例如NSObject或NSButton来清楚分辨它们属于Mac OS X核心;使用“NS”是由于这些类别的名称在NeXTSTEP开发时定下。 虽然Objective-C是C的母集,但它也不视C的基本型别为第一级的对象。 和C++不同,Objective-C不支持运运算元重载(它不支持ad-hoc多型)。亦与C++不同,但和Java相同,Objective-C只容许对象继承一个类(不设多重继承)。Categories和protocols不但可以提供很多多重继承的好处,而且没有很多缺点,例如额外执行时间过重和二进制不兼容。

和C++的比较

  1. 目前好象只有Apple使用Objective-C作为其支持的语言吧。
  2. 与C++的不同之处有:
  3. OC中所有的类都必须继承自NSObject。
  4. OC中所有对象都是指针的形式。
  5. OC用self代替this。
  6. OC使用id代替void*。
  7. OC使用nil表示NULL
  8. OC只支持单继承。
  9. OC使用YES/NO表示TRUE/FALSE
  10. OC使用#import代替#include
  11. OC中用讯息表示类的方法,并採用[aInstance method:argv]调用形式。
  12. OC支持反射机制
  13. OC支持Dynamic Typing, Dynamic Binding和Dynamic Loading。
  14. 与C++的相同之处有:
  15. 与C共享的部分一致。
  16. 可以使用assert(BOOL), 一般用NSCParameterAssert(BOOL)代替。
  17. OC中的命名前缀说明:
  18. NS-:NextStep
  19. CF-:Core Foundation
  20. CA-:Core Animation
  21. CG-:Core Graphics
  22. UI-:User Interface
  23. OC中的讯息特殊性:
  24. 调用讯息的类可以不知道如何回响这个讯息。如果它不知道如何处理这个讯息,它会自动的将这个讯息转给其他的类,比如它的父类。
  25. 调用讯息的类可以是nil。在C++中,在使用类方法之前,我们都需要检查对象是否为空,所以在实现析构函式的时候,常会有如下的代码,如if (var) { delete var; }但是在objective c中,我们就可以直接写[var release];即使var == nil, 也不会有问题。
  26. OC中的函式声明格式有:
  27. -/+ (return type) function_name;
  28. -/+ (return type) function_name : (parameter type) parameter;
  29. -/+ (return type) function_name : (parameter type) parameter1otherParameter: (parameter_type) parameter2
  30. 以上参数说明:-表示一般函式,+表示静态函式。otherParameter是参数的别名(第一个参数的别名省略),在函式调用时方便指定。
  31. OC中的构造/析构函式
  32. OC中的init()/release()对应于C++的构造/析构函式。alloc()/dealloc()也就对应于C++的new和delete,其中的dealloc()由于引用计数的自动调用而不用手动调用。
  33. OC中父类的init()/release()函式需要子类的手动调用。而且每次都必须调用。不同于C++的自动调用。
  34. 构造函式(- (id) init)调用形如:CSample* pSample=[CSample alloc] init];其中alloc(+ (id) alloc)是继承来的static函式,init是继承来的一般函式,如重写一般函式时,则相当于C++的覆盖(不带参数)或重载(带参数)。
  35. 析构函式(- (void) release)将引用计数减1,当=0时父类的release()会自动调用dealloc(- (void) dealloc);
  36. 当OC没有数据成员时,可省略{},建议保留。
  37. 继承下来的方法,如:-(id) init可以头档案中省略,建议保留
  38. OC中只有数据成员的访问限制,没有方法的访问限制。
  39. 同C++一样,数据成员有三种访问限制public, protected, private,预设是protected。
  40. 示例:@interface AccessExample: NSObject {
    @public
    int publicVar;
    @protected
    int protectedVar;
    @private
    int privateVar;
    }
    @end
  41. 方法的访问限制可通过Category实现
  42. 示例:
    @interface MyClass
    - (void) sayHello {
    NSLog(@"Hello");

    }

    @end



    @interface MyClass(Private)
    - (void) kissGoodbye;
    @end
  43. OC中没有类的静态变数,只有全局变数
  44. OC中的数组NSArray可以保存不同对象类型的数据。
  45. OC也支持runtime时的类型检查
  46. - (BOOL) isKindOfClass: classObj
    用于判断该对象是否属于某个类或者它的子类
  47. - (BOOL) isMemberOfClass: classObj
    用于判断该对象是否属于某个类(这里不包括子类)
  48. - (BOOL) respondsToSelector: selector
    用于判断该对象是否能回响某个讯息。这里,我们可以将@selector后面带的参数理解为C++中的函式指针。
    注意:1)不要忘了@ ;2)@selector后面用的是(),而不是[ ] ;3)要在讯息名称后面跟:,无论这个讯息是否带参数。如:[pSquare respondsToSelector:@selector(Set: andHeight:)]。
  49. + (BOOL) instancesRespondToSelector: selector
    用于判断该类是否能回响某个讯息。这是一个静态函式。
  50. -(id) performSelector: selector :调用对象的selector方法。
  51. conformsToProtocol 类似于respondsToSelector ,用于动态检查某个对象是否遵守某个协定。
  52. Category:在没有原始码的情况下,为一个已经存在的类添加一些新的功能
  53. 只能添加新的方法,不能添加新的数据成员
  54. Category的名字必须是唯一的
  55. Protocol:相当于C++中的纯虚类
  56. 形如:@interface MyDate: NSObject <Printing> { } @end
  57. 使用:MyDate * dat = [[MyDate alloc] init];id<Printing> var = dat; [var print]。
  58. 说明:我们首先声明了Printing 协定,任何遵守这个协定的类,都必须实现print 方法。在Objective C 中,我们通过<>来表示遵守某个协定。当某个类声明要遵守某个协定之后,它就必须在.m档案中实现这个协定中的所有方法。使用id<Printing> 作为类型,而不是象C++中的Printing* var。
  59. IBOutlet, IBAction: 这两个东西其实在语法中没有太大的作用。如果你希望在Interface Builder中能看到这个控制项对象,那幺在定义的时候前面加上IBOutlet,在IB里就能看到这个对象的outlet,如果你希望在Interface Builder里控制某个对象执行某些动作,就在方法前面加上(IBAction)。
  60. 儘量避免在一行语句中进行两层以上的嵌套
  61. 讯息转发:- (void) forwardInvocation: (NSInvocation*)anInvocation;

扩展的关键字

@interface

类型声明,类似于c++中的class,区别在于Object c中的声明与实现是强制分开的,@interface关键字用于类型的声明,包括数据成员、方法声明、属性等。方法的参数传递採用中缀符的形式,利用“:”分割参数名和被传递参数,类型的声明以@interface开头,以@end结束,通常一个类型的声明採用下面的结构:
@class someOtherObject //外部类型声明
@interfacesomeObject:NSObject //继承的类型
{
int i; //成员变数
}
-(id)someMethod:(int)someArg someOtherArgName:(int)someOtherArg; //对象的方法
+(id)someMethod:(int)someArg; //类方法
-(id)init; //初始化方法
@propertyint num; //属性
@end

@implementation

对应于@interface的类型声明,@implementation表示一个类型的实现过程,同样以@end结束,实现的格式通常如下:
@implementationsomeObject
-(id)someMethod:(int)someArg someOtherArgName:(int)someOtherArg
{
//实现代码
}
@synthesize num=i; //将属性与变数进行对应
@end

new、alloc

Object C中的方法调用形式採用讯息传送的方式,通常调用的形式如
[someObject someMethod:firstArg someOtherArgName:otherArg]
实例的初始化也採用讯息传送的形式,可以简单的调用类型的new方法来获取一个实例对象,简单实例化的方法通常是:
someObject *obj = [someObjectnew]; //类的实例化
new方法的实际过程是调用allocinit方法,因此如果需要採用自定义的方法来初始化实例,则需要自己重写init方法,通常的初始化方式为:
someObject *obj = [[someObject alloc] init]; //採用无参数的init实例化
someObject *obj = [[someObject alloc] initWithArg:Arg]; //採用参数的实例化

@class

@class是一个前向引用声明,类似于C++中的friend友元声明,其作用是告诉编译器其后面的栏位代表一个类型名称,儘管不知道类型的具体实现,但是只需要将其作为一个类型名称处理即可。通常在使用複合的结构时可以採用@class来减少头档案的相互引用,如果出现循环依赖,则需要依靠@class来避免引用的死循环。通常使用形式为:
@classsomeOtherObject;
@interfacesomeObject:NSObject
{
someOtherObject *obj;
}
@end

@property

儘管可以使用obj->arr的形式去强制读取对象的成员变数,但是良好的编程形式是对外界提供成员变数的读写接口。@property关键字提供了外界对成员变数的访问接口,其本质是为某一个属性提供set和get操作。根据不同的需要,可以添加readonly(唯读,相当于只添加get不添加set方法)或者readwrite(读写,如果不添加则为默认);还有三种赋值方式可选:assign(直接赋值,通常用于基本类型),retain(释放旧值,增加新的retaincount),copy(常用于字元串,生成一个新的拷贝)。通常使用的方式如下:
@interface someObject:NSObject
{
int i; //成员变数
}
@property (assign,readonly) int num; //属性
@end

@synthesize

@property对应,将一个外在属性与成员变数相关联,定义在@implementation中,如果属性名与变数名一致则可以省略变数名。常用方法:
@implementation someObject
@synthesize num=i;//如果属性名也为i,则可以直接写为 @synthesizei
@end

记忆体管理

Object C採用引用计数的方式进行记忆体管理,由于所有的对象都继承于NSObject,因此所有的对象都可以接受NSObject的三个方法:
-(id)retain;
-(void)release;
-(unsigned)retainCount;
retain方法将对象的引用计数加一併返回该对象,release将引用计数减一,retainCount方法返回对象当前的引用计数。当採用new、alloc、copy方法创建一个对象时,它的引用计数被置为1,如果程式中对该对象进行操作,则应根据需要,通过调用retain和release方法来保证该对象在不需要的时候被清除。当一个对象的引用计数被置为0后,系统会自动向对象传送一个dealloc讯息,将其占有的资源释放。通常情况下,如果一个对象的初始化过程调用了其他资源,则应该重写改对象的dealloc过程,保证在对象的销毁期正确释放这些资源。
为了更加方便的进行能存管理,cocoa中提供了一个自动释放池(autorelease pool)的概念,每一个类都继承了一个autorelease方法,当调用对象的autorelease方法时,改对象会被加入到开始创建的自动释放池中。当程式进行到不再需要自动释放池中的对象时,将自动释放池释放的时候会向池中的所有对象传送一个release讯息,从而保证不再需要的对象被正确的释放。通常的用法如下:
NSAutoreleasePool *pool;
pool = [[NSAutoreleasePool alloc] init];
someObject * obj = [[someObject alloc] init];
[obj autorelease]; //加入自动释放池
//其他代码
[pool release]; //执行该语句时,系统会向池内所有的对象传送release讯息;在这个例子中,如果对obj进行的其他retain操作和release操作保持一致的话,则会将obj的引用计数变为0,从而调用它的dealloc方法进行资源释放
Object C进行记忆体管理的3条规则是:
  1. 如果使用new、alloc或copy操作获得一个对象,则该对象的保留计数器值为1
  2. 如果通过任何其他方法获得一个对象,则假设该对象的保留计数器值为1,而且已经被设定为自动释放
  3. 如果保留了某个对象,则必须保持retain方法和release方法的使用次数相等。

类别

类别是为现有的类提供一个新的方法的方法,即使没有一个类的原始码,仍然可以向类中添加一个方法以方便使用。类别的主要目的有3个:将类的实现分散到多个不同的档案或框架中,创建对私有方法的前向引用,向对象添加非正式协定。
类别的声明方法:
@interfacesomeObject (someProtocal)
-(void)someMethod;
@end
类别的实现方法:
@implementationsomeObject(someProtocal)
-(void)someMethod
{
}
@end

@protocol

Object C中的协定类似于java中的接口,通过@protocol关键字定义一个或多个需要遵从协定的对象实现的方法,协定定义的方法:
@protocolsomeProtocol
-(void)someMethod;
@end
採用协定的方法是在类声明时使用尖括弧注明其需要使用的协定:
@interfacesomeObject:NSObject <someProtocol>
在类实现时需要将协定中规定的方法都予以实现。
Object C 2.0增加了2个新的协定修饰符@optional@required,可以规定协定中的方法是否为必须实现的方法。
声明:此文信息来源于网络,登载此文只为提供信息参考,并不用于任何商业目的。如有侵权,请及时联系我们:baisebaisebaise@yeah.net