百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程网 > 正文

给Android程序员看的Objective-C入门

yuyutoo 2024-11-17 03:42 2 浏览 0 评论

作者:snwrking


前言


最近两年因为公司业务需求, 我从Android开发转成了也涉猎前端的工作, 主要在做一些Android与ReactNative了.

但是众所周知的是, React Native其实是一个严重先天不足的跨平台框架. 简言之, 就是RN仅仅是一个UI框架, facebook在创建之初就是想使用yoga(跨平台的UI库)来包两个平台的UI代码. 而一旦是非UI的内容, 比如说sensor, network, security, permission, ..., 那RN就很捉急了.

当然RN并不是完全没办法, 它的做法就是分而治之, 把这些东西下放到两个native平台去做, 然后把结果通过bridge告诉js端就行了. 这一点, 其实也就意味着, 对于稍深一些的RN功能, 程序员得了解js, android, iOS平台的开发. 比如说, 我们最近要做一个本地的server, 运行在手机上. 这个明显就是非UI的内容, 所以我得在android与iOS平台上分别写代码. (其实有一个react-native-static-server的库可以参照, 但我们的需求还要读到内容后解密, 所以更复杂, 需要我们自己定制)

这样的native开发的需求, 就引发了我们js开发, android开发, 得去了解些iOS的知识. 另外, 因为RN中的iOS代码是objective-C, 所以我们学习的语言就不是swift, 而是更古老(更反人类)的OC了.


Swift 还是 OC?


上面讲过, 对于RN开发来说, 一般使用OC较多. 特别是一些特别需求, 如加密, Swift是2020年2月才有了crypto库, 以前都没有的. 这些东东都只好使用OC来开发.

另外, Swift其实底层也在利用OC, 像是selector, 所以即使使用Swift, 你还是得了解一些OC的内容.

最后, iOS开发中一个好处就是它可以直接利用C的库. OC可以方便的利用C的库. 例子有很多个

  • 线程中的GCD, 其实使用的就是C语言的GCD库.
  • iOS不像java, 不能天生支持zip压缩/解压. 这时OC可以方便利用MiniZip这样的库里的 .h, .c文件.

综上所述, 这篇文章主要还是在介绍OC


OC里的类型


数字


因为OC是C语言一系的, 所以那些复杂的数据类型在OC里都是支持的, 如short, unsigned long ... 这些类型在java中没有, 所以多提一句.

另外, 数字的字面值, java中直接使用数字就行, 如int i = 20; 但在OC中得加一个@, 表示是OC中的值(而不是C中的值), 所以OC中的数字20就是表示为 @20.


字符串


同理, OC中的String字面值, 也得前面加@. 不然的话, ""是表示C中的字符串, 也就是char[]. 只有@"", 才表示是一个NSString类型, 这是一个类, 而不是char数组了.

经常打印日志所用到的格式化输出则是用 %@来做占位符. 如:

NSString* name = @"xxx";
NSLog(@"hello %@", name); //=> hello xxx


对象


和java中不一样, java中的对象其实都是指针, 但你不用写明, 因为java本身并没有"指针"的概念. 但在C系语言中, 指针很常见. OC则是显示地认为每个对象都是指向一堆内存的指针, 所以我们得这样定义对象: NSString* name = @"xxx";.

(注意这里的*就表示是一个指针)


函数


好吧, 这可能是java/js程序员看起来最反人类的地方了.

先说结论:

  • OC中的方法调用是用中括号表示的 (其它大多数语言都是使用小括号的);
  • 参数要带参数说明
  • 而参数与参数之间用空格表示

再来看例子:

java:

String memo = "memo.txt"; 
String extension = memo.substring(5);

OC:

NSString* memo = @"memo.txt";
NSString* extension = [memo substring: 5];

要是更多参数, 那就这样: [object method:arg1 arg2Name:arg2 arg3Name:arg3] 还是举例来说明:

/* declaration */ + (NSData *)decryptContent:(NSData *)encrypted withKey:(NSData *)key; 
/* usage */      [obj decryptContent: encrypted withKey: key];

/* declaration */ - (void)stop;
/* usage */       [obj stop];

这里的withKey就是参数名, key是实参名. 在调用这个decryptContent方法时, 除了第一个参数, 都要带上参数名.

这其实就相当于java中的

obj.decryptContent(byte[] content, byte[] key);
obj.stop();


源文件


java中只有".java", js也只有".js"文件. 但是C系语言都分了头文件与实现文件. C中是 : .h, .c OC中是: .h, .m

其实.h是头文件, 类型于java中的public声明. 所有能被外部文件访问的成员与方法都定义到.h里.

.m就是真正实现. 一些不对外开放的方法成员, 在.m里也能存在.



OC中的类声明也得分两部分: interface与implementation, 分别代表定义与实现. 一般interface放到.h里去, 这样其它文件可以调用这个类. 而implementation一般写在.m文件里. 比如说:

// MyClass.h
@interface MyClass: NSObject {
  NSString* name;  //property
}
-(void)hello:(NSString*)name; //method
@end

注意:

1). 和java不同, 就是你的类是NSObject的子类, 你也得写明. java中若是Object的子类, 就不用写明extends Object也是行的.

2). 类的方法定义, 最前面是+或-.

  • +就代表static方法, 以后调用就是[MyClass func]
  • -代表成员方法, 调用使用对象, 而不是类名, 如[obj func]

3). 方法返回值放到小括号里, 如上面的(void).

4). 上面的name是参数. 在调用时就是: [obj hello:@"xx"];

实现体则是:

@implementation MyClass 
-(void) hello:(NSString*)name{
  NSLog(@"hello, %@", name);
}
@end

  • interface中只有成员/方法的定义, 没有实现.
  • implementation里就是写完方法体, 这个方法到底是干嘛的


category


这个有点类似kotlin中的extension. 即你可以任意扩展某个类. 即使这类是一个系统类, 你也可以扩展.

定义一个category就类似定义一个类, 只不过你不用写super class, 而是用(category名字)来代替父类名.

下面是一个例子. 普通NSString是没有uuid方法的. 现在我们给NSString新加一个uuid方法, 调用这个新方法就会得到一个随机uuid值.

// NSString+Uuid.h
#import <Foundation/Foundation.h>

@interface NSString (Uuid)
+ (NSString*) uuid;
@end

// NSString+Uuid.m
#import "NSString+Uuid.h"
@implementation NSString (Uuid)
+ (NSString*) uuid {
  CFUUIDRef uuidRef = ...;
  return uuidString;
}
@end


protocol


protocol就是java中的接口, 即一堆方法定义的集合. 因为都是表示抽象, 所以和java接口类似, protocol在OC中就只有.h文件, 没有.m文件.

@protocol ServerPlugin <NSObject>
  @required -(void) serve: (int) id;
@end


// if you want to use the protocol, use it as a generics:
@interface HttpServer: NSObject<ServerPlugin>;
@end


protocol中的注意事项


在java中, 我们可以使用Map<String, Iinterface>. 取出值时就是: Iinterfae obj = map.get(key);

但在OC中, 是不能使用 某Protocol obj = [map objectForKey:key]; 因为Protocol本身根本就不是一个对象, 只是一个抽象概念. 所以正确的写法是:

NSOjbect<某Protocol> plugin1 = [dictionary objectForKey:@"key1"];


内存管理


C中的内存管理是手动的, 即当你malloc申请开辟新内存块后, 你最后也得注意把这内存给free了. OC也是这样的.

但java程序员, 或者说所有程序员, 都会觉得这样好烦, 而且容易忘记free某对象的引用时, 就会内存泄露, 极易出问题. 所以在2011年, apple也引入ARC(Auto Reference Counting), 即自动帮你记录引用数, 并在脱离作用域时帮你release掉引用. 这其实就类似java中的GC. 这样OC开发总算从内存的沼泽中被释放了出来.

当然你也不是100%全自动内存管理了. 当你在处理一些C的库, 或Core Foundation框架时,这些C的部分都没有被ARC覆盖, 所以你仍得注意自己得释放到申请的内存.


总结


以上就是我作为一个Android开发, 入手OC时碰到的一些基本知识点,分享出来, 希望能帮助更多有需要的人.

文末附上大厂学长给我的资料,内容包含:Android学习PDF+架构视频+面试文档+源码笔记高级架构技术进阶脑图、Android开发面试专题资料,高级进阶架构资料 这几块的内容

分享给大家,非常适合近期有面试和想在技术道路上继续精进的朋友。也是希望可以帮助到大家提升进阶

如果你有需要的话,可以私信我【提升】我发给你


相关推荐

史上最全的浏览器兼容性问题和解决方案

微信ID:WEB_wysj(点击关注)◎◎◎◎◎◎◎◎◎一┳═┻︻▄(页底留言开放,欢迎来吐槽)●●●...

平面设计基础知识_平面设计基础知识实验收获与总结
平面设计基础知识_平面设计基础知识实验收获与总结

CSS构造颜色,背景与图像1.使用span更好的控制文本中局部区域的文本:文本;2.使用display属性提供区块转变:display:inline(是内联的...

2025-02-21 16:01 yuyutoo

写作排版简单三步就行-工具篇_作文排版模板

和我们工作中日常word排版内部交流不同,这篇教程介绍的写作排版主要是用于“微信公众号、头条号”网络展示。写作展现的是我的思考,排版是让写作在网格上更好地展现。在写作上花费时间是有累积复利优势的,在排...

写一个2048的游戏_2048小游戏功能实现

1.创建HTML文件1.打开一个文本编辑器,例如Notepad++、SublimeText、VisualStudioCode等。2.将以下HTML代码复制并粘贴到文本编辑器中:html...

今天你穿“短袖”了吗?青岛最高23℃!接下来几天气温更刺激……

  最近的天气暖和得让很多小伙伴们喊“热”!!!  昨天的气温到底升得有多高呢?你家有没有榜上有名?...

CSS不规则卡片,纯CSS制作优惠券样式,CSS实现锯齿样式

之前也有写过CSS优惠券样式《CSS3径向渐变实现优惠券波浪造型》,这次再来温习一遍,并且将更为详细的讲解,从布局到具体样式说明,最后定义CSS变量,自定义主题颜色。布局...

柠檬科技肖勃飞:大数据风控助力信用社会建设

...

你的自我界限够强大吗?_你的自我界限够强大吗英文

我的结果:A、该设立新的界限...

行内元素与块级元素,以及区别_行内元素和块级元素有什么区别?

行内元素与块级元素首先,CSS规范规定,每个元素都有display属性,确定该元素的类型,每个元素都有默认的display值,分别为块级(block)、行内(inline)。块级元素:(以下列举比较常...

让“成都速度”跑得潇潇洒洒,地上地下共享轨交繁华
让“成都速度”跑得潇潇洒洒,地上地下共享轨交繁华

去年的两会期间,习近平总书记在参加人大会议四川代表团审议时,对治蜀兴川提出了明确要求,指明了前行方向,并带来了“祝四川人民的生活越来越安逸”的美好祝福。又是一年...

2025-02-21 16:00 yuyutoo

今年国家综合性消防救援队伍计划招录消防员15000名

记者24日从应急管理部获悉,国家综合性消防救援队伍2023年消防员招录工作已正式启动。今年共计划招录消防员15000名,其中高校应届毕业生5000名、退役士兵5000名、社会青年5000名。本次招录的...

一起盘点最新 Chrome v133 的5大主流特性 ?

1.CSS的高级attr()方法CSSattr()函数是CSSLevel5中用于检索DOM元素的属性值并将其用于CSS属性值,类似于var()函数替换自定义属性值的方式。...

竞走团体世锦赛5月太仓举行 世界冠军杨家玉担任形象大使

style="text-align:center;"data-mce-style="text-align:...

学物理能做什么?_学物理能做什么 卢昌海

作者:曹则贤中国科学院物理研究所原标题:《物理学:ASourceofPowerforMan》在2006年中央电视台《对话》栏目的某期节目中,主持人问过我一个的问题:“学物理的人,如果日后不...

你不知道的关于这只眯眼兔的6个小秘密
你不知道的关于这只眯眼兔的6个小秘密

在你们忙着给熊本君做表情包的时候,要知道,最先在网络上引起轰动的可是这只脸上只有两条缝的兔子——兔斯基。今年,它更是迎来了自己的10岁生日。①关于德艺双馨“老艺...

2025-02-21 16:00 yuyutoo

取消回复欢迎 发表评论: