86437913 2019-06-27
最近要把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 <Foundation/Foundation.h> @interface Test : NSObject -(void) test; @end
这里面只定义需要外部访问的方法结构,也就是对外的方法,具体实现是在.m
文件中
类的使用,也和其他语言不太一样,我们先来看一张图
alloc
分配内存,init
才是实例化,在其他语言中new
其实执行的也是这两步[对象 方法]
这种形式,而不是以对象.方法
的形式,这和其他语言区别比较大对象.属性
代码块这个词你乍一听挺陌生,我举一个我们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); }]
oc里面的协议(Protocol)和java里面的接口(interface)比较类似,都是只定义,不实现;都需要一个类来实现这个协议和协议里面的方法。我们来看下语法:
#import <Foundation/Foundation.h> // @protocol为关健字,定义这个类是一个协议类 @protocol TestProtocol <NSObject> // @required为关健字,代表必须要实现的方法 @required - (void)req; // @required为关健字,代表未必要实现的方法 @optional - (void)opt; @end
Test.h
文件#import <Foundation/Foundation.h> // 引入协议类 #import "TestProtocol.m" // NSObject<TestProtocol>让Test类知道必须实现协议的方法 @interface Test : NSObject<TestProtocol> // 注:这里面不用定义协议类的方法,需要在.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在集成weex
的时候,需要写大量的oc
逻辑代码,这部分功能就是我们提供给现有的App的一个pod
(类似npm包),里面包括:缓存js文件、读取js文件、写weex
的扩展module、把业务类注入到pod
中使用、调试中使用到的websocket
...所以当你在实现的过程中,你自然就熟悉了这门语言。多写才是掌握OC的唯五捷径!