一、Objective-C概述
Objective-C语言是以C语言为基础的一个扩展集,它添加了OOP等很多新特性。Objective-C可用来编写iOS和OS X应用,一般使用苹果提供的Xcode作为开发环境。
Objective-C的面向对象语法源自SmallTalk,是消息传递(Message Passing)风格。消息处理到运行时(runtime)才会动态决定,给对象发送一个它无法处理的消息(只有方法声明,但没有实现),编译时可以编译通过,但在运行时会抛出异常。而在JAVA中调用某个class中不存在的方法时,编译期间就会报错。
// Objecttive-C运行时异常:undefinedMethod未定义方法
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSObject undefinedMethod]: unrecognized selector sent to instance 0x8871710'
二、基础类型
虽然Objective-C扩展自C,可以使用C语音的基础类型,但实际开发中为了风格一致较少使用,一般使用Objective-C中定义的基础类型。
基础类型 | Objective-C | OC举例 | Java | Java举例 |
---|---|---|---|---|
整数 | NSInteger | NSInteger i = 0; | int/Integer | int i = 0; |
浮点数 | CGFloat | CGFloat f = 1.0; | float/Float | float f = 1.0f; |
布尔类型 | BOOL | // 取值为OC扩展的YES/NO BOOL flag = YES; |
bool/Boolean | bool flag = true; |
字符串 | NSString | NSString *str = @"hello"; | String | String str = "hello"; |
对象 | NSObject | NSObject *obj = [[NSObject alloc] init]; | Object | Object obj = new Object(); |
在Objective-C中,为了避免命名冲突,许多函数、常量和类型名称都加了NS前缀(NeXT Software公司,后更名NeXT、Cocoa,于1966年被苹果收购)。
三、类
Objective-C的类分为声明和实现两个部分,分别放在两个文件内。声明(@interface)放在头文件中(扩展名.h),实现(@implementation)放在实现文件中(扩展名.m),以@end结束。
3.1 头文件@interface
例如:在定义文件 User.h 中定义如下:
// 自定义类需要继承自NSObject,成员变量需要放到 {} 内,如果没有成员变量可以省略 {}
#import <Foundation/Foundation.h>
@interface User : NSObject {
NSString *name;
NSInteger age;
}
@end
3.1 实现文件@implementation
然后在实现文件 User.m 中实现如下:
#import "User.h"
@implementation User {
// 实现文件可以有自己新增的成员变量
NSString *birthday;
}
@end
在Java中实现相同类的方式如下:
public class User {
public String name;
public int age;
private String birthday;
}
3.3 属性
除了像上述例子中大括号{ }内声明属性外,还可以使用@property声明属性,对比大括号的方式,@property方式声明的属性会有get()和set()方法。
#import <Foundation/Foundation.h>
@interface User : NSObject
@property NSString *name;
@property NSInteger age;
@end
3.4 方法声明
Objective-C中的方法声明的格式如下:
(1)无参数;+/- 表示是实例方法还是类方法。
+/- (返回类型) 方法名;
(2)1个参数
+/- (返回类型) 方法名: (参数1类型) 参数1形参名;
(3)2个参数;多个参数时,从第2个参数起还需要声明实参名。实参名是外部调用时的参数名,形参名是方法内部实现的参数名,一般二者命名相同
+/- (返回类型) 方法名: (参数1类型) 参数1形参名 参数2实参名: (参数2类型) 参数2形参名;
例如:在User类中新增方法,先在头文件中声明如下:
@interface User : NSObject
// 实例方法;用 - 表示
-(void) sayHello: (NSString *) friend;
// 类方法;用 + 表示
+(void) sayHelloStatic: (NSString *) friend1 friend2: (NSString *) friend2;
@end
然后,在User.m中实现如下:
#import "User.h"
@implementation User
// 实例方法;用 - 表示
-(void) sayHello: (NSString *) friend {
NSLog("hello, %@s", friend);
}
// 类方法;用 + 表示
+(void) sayHelloStatic: (NSString *) friend1 friend2: (NSString *) friend2 {
NSLog("hello, %@s , %@s", friend1, friend2);
}
@end
类似地,Java类中定义方法的格式为:
public class User {
public String name;
public int age;
private String birthday;
public void sayHello(String friend) { Log("hello" + friend) };
public static void sayHelloStatic(String friend1, String friend2) {
Log("hello" + friend1 + friend2)
};
}
3.5 方法调用
Objecttive-C中方法调用也称作消息传递。方法调用格式如下:
// [对象/类 方法名: 参数];对应 Java 的obj.method(param)
[obj method: param];
// 方法连续调用时,采用嵌套的形式;对应 Java 的obj.methodA(paramA).methodB(paramB)
[[obj methodA: paramA] methodB: paramB]
例如:创建User对象时的方法调用如下:
// 创建对象分为两部分:先分配内存,再调用初始化。等同与[NSObject new]。
NSObject *obj = [[NSObject alloc] init];
// 创建User对象,并调用其实例方法
// 创建对象时,alloc init和new是等价的。Cocoa惯例是使用alloc init
User *user = [User new];
// 实例方法
[user sayHello: @"jack"];
// 类方法
[User sayHelloStatic: @"jack" friend2: @"rose"];
3.6 继承
在3.4小节中已经看到了继承的用法(所有类都需要继承自NSObject):
@interface User : NSObject
-(void) sayHello: (NSString *) friend;
@end
// 例如Student类继承自User类
@interface Student : User
@end
另外Objective-C中使用super和self关键字分别表示父类和自己,例如:
#import "Student.h"
@implementation Student
@property NSString *className;
-(void) sayHello: (NSString *) friend {
// 父类的name属性
NSLog("name, %@s", [super name]);
// 自己的className属性
NSLog("className, %@s", [self className]);
}
@end
四、Foundation常用类
Foundation框架是Objective-C的基础框架。UIKit框架(iOS开发)、AppKit框架(OS X开发)都需要依赖Foundation框。
4.1 字符串
Objective-C里的字符串是NSString,由双引号包裹并在引号前加一个@符号,例如:
// 字符串前的@表示字符串应该作为NSString类型处理,而不是作为C语音的字符串处理
NSString str = @"hello";
// NSString 作为参数传入 %@
NSLog(@"hello, %@", @"");
类 | 说明 | 常用方法 |
---|---|---|
NSString | 不可变字符串,类似java的String | 1. 比较字符串是否相等-(BOOL) isEqualToString: (NSString * ) aString) 2. 比较字符串是否相等,可选option来不区分大小写比较-(NSComparisonResult) compare: (NSString * ) aString) options: (NSStringCompareOptions) mask; 3. 判断前缀-(BOOL) hasPrefix: (NSString * ) aString) 4. 判断后缀-(BOOL) hasSuffix: (NSString * ) aString) |
NSMutableString | 可变字符串,类似java的StringBuffer | 添加新字符串:-(void) appendString: (NSString * ) aString; |
4.2 集合
类 | 说明 | 常用方法 |
---|---|---|
NSArray | 不可变数组 | 1. 数组大小: -(NSUInteger)count; 2.获取特定索引处对象:-(id)objectAtIndex:(NSUInteger)index; 或者使用C语言语法array[0] |
NSMutableArray | 可变数组 | 添加对象: -(void) addObject: (id) anObject; |
NSDictionary | 不可变字典 | 使用类方法创建固定大小的字典:+(id) dictionaryWithCapacity: (NSUInteger) numItems; |
NSMutableDictionary | 可变字典,类似Java中的HashMap | 1.添加元素: -(void)setObject:(id) anObject forKey:(id)aKey; 2.删除元素: -(void)removeObjectForKey:(id) aKey; |
五、协议protocol
Objective-C的协议类似Java的接口interface。声明协议使用@protocol关键字,并使用@optional和@required表示协议的方法是否必须实现,如下所示:
@protocol MyProtocol
@optional
- (void) testFun;
@required
- (id) copy;
@end
// 声明协议时如果需要继承其他协议,使用<>表示,例如MyProtocol协议继承MySuperProtocol:
@protocol MyProtocol<MySuperProtocol>
@end
在类中实现协议时,首先在类的@interface中使用<>声明需要实现的协议,然后在@implementation中完成实现。如下所示:
@interface User<MyProtocol>
@end
@implementation User
- (id) copy {}
@end
六、类别category
Objective-C的类别(category)类似kotlin的扩展函数,可以为现有的类添加新方法。声明类别的方式如下:
@interface 类名(类别名)
+/- (方法返回类型)方法名;
@end
// 使用扩展方法时需要倒入类别如下所示:
#import "类名+类别名.h"
例如为NSString类扩展一个print方法,@interface和@implementation分别如下:
// 声明类别:
@interface NSString(NSStringConvenience)
- (void)print;
@end
// 实现如下:
@implementation NSString(NSStringConvenience)
- (void)print {
NSLog("hello, %@", self);
}
@end
// 使用方式如下
#import "NSString+NSStringConvenience.h"
int main() {
NSString str = @"hello";
// 使用扩展方法
[str print];
}
The End
欢迎关注我,一起解锁更多技能:BC的掘金主页~💐 BC的CSDN主页~💐💐
官方文档:https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/Introduction/Introduction.html
发表评论