Objective-C基础教程一

时间:2022-09-07 08:25:38

1,#import

Objective-C使用头文件来包含元素声明,这些元素包含结构体,符号常量,函数原型等。和C语言的#include差不多。

#import是GCC编译器提供的,Xcode在编译Objective-C,C和C++程序时都会使用它。#import可保证头文件只被包含一次,而不论此命令实际上在哪个文件中出现多少次。

ps,在C语言中,程序员通常使用基于#ifdef命令的方案来避免一个文件包含另一个文件,而后者又包含第一个文件的情况。

而在Objective-C中,程序员使用#import实现这个功能。


2,NSLog和字符串

NSLog方法和android中Log作用是一致的。

NSLog(@"Hello, Objective-C"); @符号是OC在标准C语言基础上添加的特性之一。双引号中 的字符串前有一个@符号,这表示引用的字符串应该作为Cocoa的NSString元素来处理,也就是字符串。



3,OOP的一个关键概念:间接(indirection)。

含义是---不在代码中直接使用某个值,而是使用指向该值的指针。

间接和变量,其实就是将多处出现的上限值定义为个变量count,就是让代码更易于扩展(修改一处就即可)。

根本的意义和设计模式的精神是一致的,找出可能需要变换之处,把它们独立出来,不要和那些不需要变换的代码混在一起。



4,面向对象编程

过程式程序建立在函数之上,数据为函数服务。面向对象编程从相反的角度来看待问题,它以程序的数据为中心,函数为数据服务。在OOP中,不在重点关注程序中的函数,而是关注于数据。

具体是如何工作呢?在OOP中,数据通过间接方式保护对自身操作的引用代码。不是通知drawRectangle()函数“使用这个形状结构绘制矩形”,而是要求矩形“绘制自身”。通过间接方式的威力,矩形数据知道如何查找相应的函数绘制图形。


5,id

id代表的是identifier,标识符。id是一种泛型,可以指向任何类型的对象,实际上是一个指针。

void drawShapes(id shapes[], int count)
{
int i;
for(i = 0; i < count; i++){
id shape = shares[i];
[shape draw];//方法调用
}
}


6,Objective-C中的OOP

@interface,就是java的class,声明了类的结构。

@interface Circle : NSObject
{
ShapColor fillColor;
}
- (void) setFillColor: (ShapeColor) fillColor;
- (void) draw;
@end//Circle;


7,中缀符

方法的名称及其参数都是合在一起的。例如,你可以这样调用带一个参数的方法:

[circle setFillColor: kRedColor];


8,@implementation 和@interface对应,一个声明,一个是具体的实现内容。

@implementation  Circle
-(void) setFillColor: (ShapeColor) c
{
fillColor = c;
}//setFillColor

-(void) draw
{
//TODO
}
@end//Circle


9,对象实例化

[Circle new];

[[Circle alloc] init];

不过,cocoa习惯使用alloc和init来创建对象,而不是new
使用alloc来分配内存,并使用init来初始化,会将这块内存全部清0,bool型为NO,int型为0,指针为nil

参考:http://www.oschina.net/question/54100_32468

一般情况下,我们在Objective-C中定义一个类时,总要提供一个初始化方法,一般大家都是这样写的:

- (MyClass *)init 
{
self = [super init];
if (self) {
//执行一些资源、变量的初始化工作
}
return self;
}

这样一段简单的代码,却有很多可以思考的问题:
1、为什么要通过[super init]来调用父类的初始化方法,父类的初始化方法里又执行了什么东西?

      首先,我们知道对象继承的概念,一个子类从父类继承,那么也要实现父类的所有功能,这就是is-a的关系,比如说狗是哺乳动物,那么狗必定具有哺乳动物的特征和功能。所以在子类的初始化方法中,必须首先调用父类的初始化方法,以实现父类相关资源的初始化。例如我们在初始化狗这一对象时,必须先初始化哺乳动物这一对象,并把结果赋予狗,以使狗满足属于哺乳动物这一特征。

     典型的,在iOS下,所有的类都继承于NSObject,而NSObject的init方法很简单,就是return self。当父类的初始化完成之后,即self不为nil的情况下,就可以开始做子类的初始化了。


2,至于init和new的区别

new方法是NSObject对象的一个静态方法,根据apple的文档,该方法实际上就是alloc和init方法的组合,实际上二者是一样的,但 apple还是推荐我们使用第一种方法,为什么呢?因为使用第一种方法,你可以使用自己定义的init方法来做一些初始化,当然,如果子类没有提供 init方法,自然调用的就是父类的init方法了。所以说,从安全性的角度来收,作为开发者我们在对象使用之前是一定要对对象进行初始化的,因此在定义类的时候一定要提供初始化方法。但是否一定要使用init作为方法名呢?答案是不一定。使用init作为方法名只是你重写了NSObject的init方法而已,如果你自己重新定义一个初始化方法,也是完全可以的,只要你在使用的时候记得调用新定义的初始化方法就可以了。


补充:
在面向对象编程中,如果编写一个类而没有包含构造函数,这个类仍能编译并且完全可以正常使用。如果类没有提供显式的构造函数,编译器会提供一个默认的构造函数给你。除了创建对象本身,默认构造函数的唯一工作就是调用其超类的构造函数。在很多情况下,这个超类是语言框架的一部分,如java中的 Object类,objective-c 中的NSObject类。

不论是何种情况,在类中至少包含一个构造函数是一种很好的编程实践,如果类中有属性,好的实践往往是初始化这些属性。
——以上摘自《The Object-Oriented Thought Process》 by Matt Weisfeld



10,和java里的字符串类似,==是比较是否是同一个对象,比较字符串是否相等用isEqualToString。