概述
本文的主要内容就是将OC的大体的语言特征总结一下。
一 Objective-C语言
初识OC
Objective-C:C的超集
Objective-C中可以使用C,目的就是C的基础上加入面向对象。
Objective-C代码的文件扩展名
.h :头文件。类,类型,函数,常数声明
.m : 源代码。实现
引入文件使用使用 #import
二 消息传递
OC中使用消息传递模型(message passing),它不同于C++和Java中的方法调用。接受消息的对象可以没有这个方法,那就会抛出异常,不会崩溃。例如一个类中没有这个方法,但是它的一个实例调用这个方法了,可以通过编译,运行期则抛出异常。
一个对象收到消息之后,他有三种处理消息的可能手段,第一是回应该消息并运行方法,若无法回应,则可以转发消息给其他对象,若以上两者均无,就要处理无法回应而抛出的例外。只要进行三者之其一,该消息就算完成任务而被丢弃。若对"nil"(空对象指针)发送消息,该消息通常会被忽略,取决于编译器选项可能会抛出例外
三 语言基础
3.1 字符串
OC中使用NSString来表示字符串。
NSString* myString = @"My String";//快捷方式创建一个字符串
NSString* anotherString = [NSString stringWithFormat:@"%d %s", 1, @"String"];//使用NSString来完成一个字符串的拼接
// 从一个C语言字符串创建Objective-C字符串
NSString* fromCString = [NSString stringWithCString:"A C string"
encoding:NSASCIIStringEncoding];
3.2 类
由声明和实现两部分组成。
声明:
由 @interface 编译选项开始,由 @end 编译选项结束。
示例如下:
@interface MyObject : NSObject {
int memberVar1; // 实体变量
id memberVar2;
}
+(return_type) class_method; // 类方法
-(return_type) instance_method1; // 实例方法
-(return_type) instance_method2: (int) p1;
-(return_type) instance_method3: (int) p1 andPar: (int) p2;
@end
实现:
关键字@implementation作为区块起头,@end结尾。
在实现中有但是在声明中没有的方法为了实现实例中的私有化。
创建对象
两种写法:
1.传统的(有参数就传参数)
MyObject * my = [[MyObject alloc] init];
alloc的作用是分配内存,init则是初始化对象
可以重写init方法,完成初始化操作。(类似于C++和java中构造方法)
2.快捷无参数
MyObject * my = [MyObject new];
3.3 方法
分为实例方法和类方法,和java中一样,这里用“-”和“+”表示。
调用
实例方法
先创建一个类的实例,再用实例来调用方法。
//可以使用嵌套调用,来消除过多的变量声明。
[[myAppObject getArray] insertObject:[myAppObject getObjectToInsert] atIndex:0];
类方法
属于这个类的方法。
类方法的典型用途是用做创建新的类实例的工厂方法,或者是访问类相关的共享信息的途径。
3.4 属性
使用属性标记符号来替换get和set语法,实际作用和get与set相同(系统为我们生成set和get方法)。
声明中@property来标记。
示例如下:
@interface Person : NSObject {
//声明两个成员变量
@public
NSString *_name;
@private
int _age;
}
//声明两个属性
@property(copy) NSString *name;
@property(readonly) int age;
-(id)initWithAge:(int)age;
@end
重点:
实现中用@synthesize关键字来标记。@dynamic关键字表明访问方法会由程序员手工提供。
@implementation Person
@synthesize name = _name;//将成员变量赋值给属性
@dynamic age;
-(id)initWithAge:(int)initAge
{
age = initAge; // 注意:直接赋给成员变量,而非属性
return self;
}
-(int)age
{
return 29; // 注意:并非返回真正的年龄
}
@end
属性的使用
属性可以利用三种方式来调用
- 传统的消息表达式
- 点表达式
- “valueForKey:”/"setValue:forKey:"方法对来访问。
示例代码:
Person *aPerson = [[Person alloc] initWithAge: 53];//传统的消息表达式
aPerson.name = @"Steve"; // 注意:点表达式,等于[aPerson setName: @"Steve"];
NSLog(@"Access by message (%@), dot notation(%@), property name(%@) and direct instance variable access (%@)",
[aPerson name], aPerson.name, [aPerson valueForKey:@"name"], aPerson->name);//方法对
为了利用点表达式来访问实例的属性,需要使用"self"关键字:
示例代码:
-(void) introduceMyselfWithProperties:(BOOL)useGetter
{
NSLog(@"Hi, my name is %@.", (useGetter ? self.name : name)); // NOTE: getter vs. ivar access
}
类或协议的属性可以被动态的读取。(类似于java中利用Class的方法来获取里面的方法和属性)
示例代码:
int i;
int propertyCount = 0;
objc_property_t *propertyList = class_copyPropertyList([aPerson class], &propertyCount);
for ( i=0; i < propertyCount; i++ ) {
objc_property_t *thisProperty = propertyList + i;
const char* propertyName = property_getName(*thisProperty);
NSLog(@"Person has a property: '%s'", propertyName);
}
3.5 快速枚举
和java中遍历一个意思。
以下循环的功能是相等的,但性能特性不同。
// 使用NSEnumerator,和java中使用Iterator一样
NSEnumerator *enumerator = [thePeople objectEnumerator];
Person *p;
while ( (p = [enumerator nextObject]) != nil ) {
NSLog(@"%@ is %i years old.", [p name], [p age]);
}
// 使用依次枚举,和java中普通遍历
for ( int i = 0; i < [thePeople count]; i++ ) {
Person *p = [thePeople objectAtIndex:i];
NSLog(@"%@ is %i years old.", [p name], [p age]);
}
// 使用快速枚举,和java中强制for循环一样
for (Person *p in thePeople) {
NSLog(@"%@ is %i years old.", [p name], [p age]);
}
3.6 协议(Protocol)
类似于java中interface接口,但是里面方法可以用Optional来变成可选实现方法。
语法
协议以关键字@protocol作为区块起始,@end结束,中间为方法列表。
示例:
//协议
@protocol Locking
- (void)lock;
- (void)unlock;
@end
声明
@interface SomeClass : SomeSuperClass <Locking>
@end
实现
@implementation SomeClass
- (void)lock {
// 實現lock方法...
}
- (void)unlock {
// 實現unlock方法...
}
@end
3.7 动态类型
类似java中泛型。
下面示例一个比一个要求严格。
下面三个方法,差异仅在于参数的形态:
- setMyValue:(id) foo;
id形态表示参数"foo"可以是任何类的实例。
- setMyValue:(id ) foo;
id表示"foo"可以是任何类的实例,但必须采纳"aProtocol"协议。
- setMyValue:(NSNumber*) foo;
该声明表示"foo"必须是"NSNumber"的实例。
3.8 转发
转发有特定的声明和实现规定,可以用于实现观察者,代理等设计模式。
3.9 类别 (Category)
和java中的“多态”同样的作用。
3.10基本数据类型
参看:
基本数据类型
四 垃圾收集
这里只是简单的了解,不做深入的展开,等到后面会有深入的剖析。(如果有c或者java基础或者其他语言基础的可以对比来看)。
可以参看一下:https://www.jianshu.com/p/48665652e4e4
五 工具类
打印日志
NSLog用于打印
数组
NSMutableArray 和 NSArray 是 ObjectiveC 中使用的数组类,前者是可变数组,后者是不可变数组。如下:
NSMutableArray *aMutableArray = [[NSMutableArray alloc]init];
[anArray addObject:@"firstobject"];
NSArray *aImmutableArray = [[NSArray alloc]
initWithObjects:@"firstObject",nil];
字典
iOS中字典和java中JsonObject一样
NSMutableDictionary和NSDictionary是Objective中使用的字典,前者可变词典,后者不可变词典,如下所示:
NSMutableDictionary*aMutableDictionary = [[NSMutableArray alloc]init];
[aMutableDictionary setObject:@"firstobject" forKey:@"aKey"];
NSDictionary*aImmutableDictionary= [[NSDictionary alloc]initWithObjects:[NSArray arrayWithObjects:
@"firstObject",nil] forKeys:[ NSArray arrayWithObjects:@"aKey"]];