Objective-c 语法,类/属性/函数(iOS学习笔记,从零开始。)
一、OC常识
- Objective-C是C的超集,也就是说C有的Objective-C都有,Objective-C多了C自身没有的OO(面向对象)特性。
- Objective-C默认扩展名为 .m 。头文件扩展名跟普通C一样 .h 。
- Objective-C推荐引入头文件的方式为:#import ,等同于C++的#include
二、从“类”说起
类是面向对象程序员赖以生存的工具。
在C++、Java和C# 中,定义一个类都使用关键字class,而在OC(Objective-c)中,定义一个类的关键字却变成了@interface.如图1
上图(1)
1. 类定义在@interface和@end之间,类名MyClass 继承自NSObject。
2.大括号{ }中定义类的属性成员。
3.函数定义,其中“-/+”定义的是方法访问权限,-定义的是对象的方法,+定义的是类的方法,类似C++的静态函数。
4.访问权限:Objective-C也像C++一样有 public private protect 三种访问权限,默认的权限是protected。
public 关键字修饰资源,可以在任何地方访问。
protected 关键字修饰资源,可以在类内和其子类里访问。
private 关键字修饰资源,只能在类内访问。
例如:iOS自带的UITableView定义就又@private
UIKIT_CLASS_AVAILABLE(2_0)@interface UITableView :UIScrollView <NSCoding> {
@private
UITableViewStyle _style;
.....
}
5.类的实例化:
MyClass *c = [[MyClass alloc] init];这里【不能】像C++那样:MyClass c; 来实例化一个Person的变量。另Objective-C都是使用指针来操作对象的。
三、再说属性
属性的定义 Object-C的对象可以使用强类型引用和弱类型引用,从上图1中得知:
MyClass *myObject1; // Strong typing 强类型的定义方法,该定义方法与C++类似,容易理解
id myObject2; // Weak typing
其中 id myObject2是一种弱类型的定义方法,弱类型的对象主要用于集合类,集合类的对象通常在运行时才知道集合中内部的对象类型定义。弱类型的引用的使用与OC的动态类型绑定(Dynamic typing)息息相关,在OC中,每一个对象包含一个成员变量isa,保存着对象属于哪一个类的类型信息。于是,开发人员能够在运行时刻知道对象的定义,例如,其父类是什么,实现了什么函数等。
总结:id 这个类型让人费解,通常id这个词不太可能是数据类型。其实我把它理解成void* 或者uint类型,代表是一个指针的意思。在使用的时候强行转换为具体的类型,这也是C++惯用的做法。
属性声明property的语法为:
@property (参数) 类型 名字;例如helloworld里的AppDelegate类的头文件如下:
#import <UIKit/UIKit.h>
@class ViewController;
@interface AppDelegate :UIResponder <UIApplicationDelegate>
@property (strong,nonatomic)UIWindow *window;
@property (strong,nonatomic)ViewController *viewController;
@end
1,读写属性(readwrite/readonly):顾名思义不用多说
2,设置属性(assign/retain/copy):assign为直接赋值,适合数值类型的;retain最常用,一般对象都用这个代表保留;copy为复制,多用于字符串。
3,原子性atomicity(nonatomic):默认是atomic,如果是多线程的程序要保证某一个成员变量的一致性,须使用 atomic。
四、函数定义、调用
Object-C的函数定义和调用都比较怪异,为了让对象执行某个操作,需要向对象发送消息,因此,函数的调用被称作Object Messageing。其消息的定义是[Receiver Message],前者是接收消息的对象,后者是消息的本身。此处先看看函数的定义:图2
上图(2)
函数的定义由函数的类型标记(Method type identifier)、返回值(return type)、一个或者多个的函数签名关键字(Method signature)、参数的类型和命名信息组成。
从上图中我们很难看到函数的名字和参数是什么!
那么,函数的真实命名由各个级联的函数签名关键字组成。例如上述函数定义中函数真实的命名是:“insertObject:atIndex:”,
函数的形参就是anObject和 index两个。
tips:当注册回调函数的时候,这个函数签名关键字一定要带上":"冒号,比如:
这里的RegressionSlideCB原型是:- (void)RegressionSlideCB:(NSTimer*)theTimer把这个函数注册到NSTimer里。
原始代码如下:
iRegressionPer = [NSTimer scheduledTimerWithTimeInterval:0.1f target:self selector:@selector(RegressionSlideCB) userInfo:nil repeats:ETrue];
NSTimer死活不回调RegressionSlideCB,很是纳闷儿。
注意:@selector(RegressionSlideCB)函数关键字后面没有冒号,害的我查半天。加上冒号就是完整的函数名字了。
Objective-C的这种signature,看似是Objective-C独有的,但是,读过《深度探索C++对象模型》这本书的同学会发现,C++在处理基类和派生类的相同函数时,如何区分的问题。也用到signature的方法,即把“参数和函数名称编在一起”。相信OC和C++都有相互借鉴。
函数调用,再来看一个例子:
//函数定义
- (int)changeColorToRed:(float)red green:(float)green blue:(float)blue;
//函数调用
[self changeColorToRed:5.0 green:2.0 blue:6.0];
上面第二行代码,如果用C++的思维会是 myColor->changeColorTo(5.0,2.0,6.0),现在看来虽然OC函数定义,乍看起来比较费解
,但是调用的时候更像是再阅读一段文字。
总结:这就是OC的优雅之处吧,也开始慢慢喜欢OC的风格了,至少在写代码时不用按住shift来输入小括号了。哈哈!也许让一个编程零基础的新人,他会觉得OC的方式更容易理解。
以上部分内容摘自博客: http://blog.csdn.net/shallon_luo/article/details/6217663,对博主的奉献精神表示感谢。