背景
最近要把weex
集成到App中,需要给iOS
和安卓
提供库文件,这里的库文件并不是WeexSDK
,而是连接iOS
和Weex
的中间件,所以就接触到oc
,如果你也和我一样,需要集成weex
,那恭喜你,oc
你也需要学习。你可能会有个疑问,不是有专职的iOS
工程师嘛,干嘛还需要前端来写,我是这么想的:
- 首先你是
weex
的发起者,同时你也是推动者,App要集成这项目技术,iOS工程师当然希望集成越简单,对现有功能影响越小越好,那自然不能把weex
和他们的代码混到一起,那这块相对独立的功能自然是前端来做最合适 - 其次这是了解全面了解
iOS
的一次绝佳的机会,爱学习的你,真的愿意拱手相让么? - 以后三端的界限会变的不那么清晰了,现在都在提大前端,多接触其他领域也是件好事
前面的话
既然我们是做前端的,对一门新语言只要大致知道语法还有这门语言的特点(这块会着重介绍),不过三天,你会写的js一样熟练,好,我们开始我们的第一个Hello World!
开始第一个程序
我们先使用xcode
来开发入门的IDE
。新建项目的时候,我们需要注意一下,既然是入门语法(不涉及画UI),我们没有必要搞那么复杂,就选择最简单的类型:命令行。
运行结果:
新建完成之后,我们就能看到main.m
文件,使用cmd+R
来运行,就可以在命令行看到效果,下面我们来依次介绍语法,保证简洁!
基本类型
-
int
类型没啥好说的,就这样定义就行:int a = 10;
-
string
类型比较特殊,字符串属性对象类型,所以我们定义时,在字符串前面需要加一个@
,变量名称前加*
,这样定义:NSString *name = @"james";
其中NSString
就代表字符串类型。
占位符
占位符应用比较多的场景是NSLog
,也就是我们js的console.log
,打印变量是我们开发中常用到的功能,oc
中我们使用占位符来代表变量,比如我们要打印int age = 10; NSString *name = @"james";
,我们可以这样做:
NSLog(@"姓名:%@,年龄:%d", name, age);
其中:%@
代表对象类型的占位符;%d
代表整型的占位符。
方法
单参数/无参数方法
在oc
中,方法的定义比较特殊,差不多长这样:
+ (void) test {
NSLog(@"Hello World!");
}
- (NSString *) test1:(NSString *)key {
return key;
}
这里面你发现没有function
这样的关健字,
-
+
号代表静态方法,-
号代表实例方法(需要实例化后才能使用) - 括号里面代表返回值,
void
代表无返回 -
test
和test1
代表方法名称 -
(NSString *) key
代表参数类型和参数变量名
多参数方法
多参数的方法,在这里要好好的说一下,初始接触oc,你肯定会觉得莫名其妙,我们先来看下多参数方法的定义:
-(void)login:(NSString *)userName password:(NSString *)pwd {
NSLog(@"userName=%@, password=%@", userName, pwd);
}
看起来是不是有点蒙,这和我们之前任何一种语言方法的定义都不一样,现在我们一张图就能说明白,看懂了之后,习惯就好了
类的介绍
任何面对对象的语言都有类,oc也不例外,新建类的时候,我们选择:macOS
-->Cocoa Class
,这样在项目中,你会发现两个文件,一个*.h
文件和*.m
文件,下面我们分别介绍
*.h
文件的作用
#import
@interface Test : NSObject
-(void) test;
@end
这里面只定义需要外部访问的方法结构,也就是对外的方法,具体实现是在.m
文件中
类的使用
类的使用,也和其他语言不太一样,我们先来看一张图
- 类的实例化需要两步:
alloc
分配内存,init
才是实例化,在其他语言中new
其实执行的也是这两步 - 类对方法的调用使用的是
[对象 方法]
这种形式,而不是以对象.方法
的形式,这和其他语言区别比较大 - 点的方式也用的到,就是获取对象属性的时候,就是使用这种形式
对象.属性
代码块(block)
代码块这个词你乍一听挺陌生,我举一个我们js里面经常用的例子,你就明白了。
function add(age, cb) {
age += 1
cb(age)
}
add(20, function(newAge){
console.log(newAge)
})
oc里面的代码码对应的就是add
方法中的cb,js是因为是弱类型语言,所以不需要定义类型,但是oc是强类型的,要用就必须定义,那cb是啥类型呢,就是代码块类型!其实这种类型解决的一个主要问题就是异步回调,和我们js里面的用法差不多,我们看下oc里面怎么使用
// 定义一个block
typedef void(^callbackBlock)(NSString *data);
// 定义方法
+ (void)ajax:(NSString *)url cb:(callbackBlock)aCallback {
......
aCallback(@"Hello")
......
}
// 使用方法
[YourClass ajax:@"xxxx", cb:^(NSString *data){
NSLog(data);
}]
协议(Protocol)
oc里面的协议(Protocol)和java里面的接口(interface)比较类似,都是只定义,不实现;都需要一个类来实现这个协议和协议里面的方法。我们来看下语法:
- 定义协议
#import
// @protocol为关健字,定义这个类是一个协议类
@protocol TestProtocol
// @required为关健字,代表必须要实现的方法
@required
- (void)req;
// @required为关健字,代表未必要实现的方法
@optional
- (void)opt;
@end
- 引入协议:
Test.h
文件
#import
// 引入协议类
#import "TestProtocol.m"
// NSObject让Test类知道必须实现协议的方法
@interface Test : NSObject
// 注:这里面不用定义协议类的方法,需要在.m文件中定义和实现
@end
- 实现协议:
Test.m
文件
#import "Test.h"
@implementation Test
-(void)req {
NSLog(@"实现协议方法");
}
// 注:就算是@required方法,类中不实现依然不会报错,编译也能通过,只是给个警告
@end
看完了你可能会觉得这玩意有啥用啊,其实协议的用途主要是在运行时(runtime),尤其是weex
和已有项目集成时,如果没有这个东西,根本就集成不起来,这块内容我们后面会说。
json
对象与oc
oc
中存储json
对象的类型是:NSDictionary
,我们来看下我们前端经常使用的一些json
方法
- 字符串转
json
NSString *jsonString = @"{\"id\":1}";
// 先转成NSData类型
NSData *jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
// 再转成NSDictionary
NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:nil];
// 根据key获取value
NSLog(@"%@",dic[@"id"]);
-
json
对象循环
for (NSString *key in dic) {
NSLog(@"key=%@, value=%@", key, dic[key]);
}
结语
其实这篇文章并不没有教你在oc中for循环怎么写,if/else怎么写,因为你写过js,这些根本就不用教,自然就会,我写的都是oc
这门语言,我在使用过程中,和javascript
以及java
中,需要注意的地方,同时我也没有说UI方面的东西,比如按钮怎么写、怎么设置背景颜色...原因有两个:
- 这里面主要针对
weex
集成到App中提供的公共服务,根本就涉及不到UI - 如果上面的东西熟练了,UI其实就是类调用方法,没啥特殊的地方,哪里不会Google哪里就好
在集成weex
的时候,需要写大量的oc
逻辑代码,这部分功能就是我们提供给现有的App的一个pod
(类似npm包),里面包括:缓存js文件、读取js文件、写weex
的扩展module、把业务类注入到pod
中使用、调试中使用到的websocket
...所以当你在实现的过程中,你自然就熟悉了这门语言。多写才是掌握OC的唯五捷径!