30天从零接手ios开发

2023-10-27 16:31:07 浏览数 (1)

由于公司原因,唯一会ios的伙伴要离开了,临时要接手ios的开发任务,只有30天的交接时间,记录下这个过程

一开始,给自己定的步骤是这样的

  1. 学习objective-c语言(书本:objective-c应用开发全程实录)
  2. 学习ios基础(iOS开发实战:从入门到上架App Store(第2版))
  3. 学习ios高级(后续阶段,不在第一阶段范围,书本:iOS开发快速进阶与实战)
  4. 熟悉系统框架,热门第三方库,jenkins打包,App Store,开发者账号相关,CocoaPods,调试、bugly线上问题定位

主要选择的是文字类的资料,不考虑视频,因为视频资料学习起来多花时间,不适合,目的是为了快速接手工作,学习的重点如下: 学习OC、学习UI绘制、学习各种事件响应,学习数据加载和传递、学习动态自适应UI

objective-c的学习

ios开发最新的书籍都是6年前的了,最近几年都没有入门的ios开发的书籍出来,看来最新学ios的人太少了吧

oc的学习过程没什么问题,大概耗费5天的时间,看完了objective-c应用开发全程实录这本书,oc的数据类型和语法跟Android,JS都不一样,要重新了解,这里面比较坑的是IB的界面开发,学习了一半半,进度缓慢,一个是最新的Xcode界面跟书本的有差距,另外是学着有点怀疑这个不好满足实际业务开发,后来经过了解,实际项目中,已经不用IB界面开发了,都是手写布局,遂放弃,还好及时止损,没有占用太多精力在上面

这本书跟ios开发基础这本书内容有诸多重叠,故直接跳过这个步骤了,加快进度

ios开发基础

首先是熟悉Xcode这个IDE,然后直接基于现有项目的一个简单的页面,自己手动实现一遍,我挑选的是设置页,不涉及网络请求,只是布局的展示,花了三天的时间(本职工作外的时间),把这个页面自己手动写出来;对照着官方的组件文档,熟悉界面布局的方法和功能

这个设置页,使用了UITableView,要熟悉这个view匹配的UITableViewDataSource这个delegate的11个回调方法,和UITableViewDelegate的十几个回调方法;还有熟悉字体,颜色大小等各种布局的写法,刚开始写还是有点吃力

上手过程中,很不习惯的还有IDE,要重新熟悉Xcode的快捷键,还有很多功能,其他IDE有提供,但是Xcode上没有,只能手动写

同样的数据跟UI绑定,ios上实现会比Android复杂不少,需要实现的回调也会多不少,不过效果上ios更强大,可以实现更多的功能;不过都统统被H5的Vue吊打,各种前端对比后,Vue是最方便简单的

现有项目的熟悉

对于现有项目熟悉,列取了一个清单如下

  1. 手写UI布局,了解了字体字号,自适应的布局,常见的UI组件的使用,富文本,事件响应,布局层级,渐变这些场景
  2. 基于网络请求的复杂列表的布局动态实现,数据模型配置
  3. 熟悉页面跳转,传参,路由配置
  4. 项目的整体架构设计,全局扩展方法配置
  5. 了解项目网络架构设计
  6. 数据存储,全局token,登入状态,userCode的动态监听,token失效如何触发所有页面的刷新机制
  7. 崩溃的定位(本地崩溃,线上崩溃)
  8. 断点调试(条件断点,全局断点,调用断点)
  9. Jenkins打包的配置,开发账号续费,证书维护,TestFlight发布,审核上线
  10. touch事件在不同层级view的传递和拦截机制,手势处理,可以处理复杂UI交互
  11. 多线程的处理
  12. 多媒体,权限,相册的处理
  13. 性能优化,内存泄露的排查,卡顿跟耗时方法的定位
  14. ios推送机制的了解
  15. 了解项目依赖的第三方的库的场景和使用

熟悉方式主要就是看现有项目的代码,不懂的就配合官方文档查看,或者Google搜索,问交接的同事等

这个清单,优先级最高的,是跟UI布局,网络和Jenkins打包相关的,这部分先熟悉上手,考虑到时间因素,上面列取的点只有60%先做了了解,其他的只能放后面待有空了,再来补上

实际需求上手

光熟悉代码还远远不够,还是要自己独立完成需求开发,刚好目前手上有两个ios的开发需求,于是就拿来练手

实际写代码,一开始最难的是不熟练,对OC语言的不熟练,对ios组件的不熟练,对项目封装的全局方法的使用不熟练;这个时候,最好的办法,就是参考其他页面类似的功能,看它是怎么写的,再照搬做下修改调整,相对于自己从零开始写,会快很多;写到后续稍微熟练后,同个功能,ios的实现耗时大概是Android的两倍,如果是一个全新的功能,没有其他页面可以参考的话,耗时还会更大的增加

另外实际开发中,对于实现效果也会有一些妥协,比如首页的资质证明功能,是上下两个UI,我采用的是写死布局位置的方法,当一个不可见,另外一个更新新的布局位置,而不适用动态的约束布局,自动适应(对这个布局写法不熟悉),时间赶,所以先妥协的实现了;这种类似妥协的地方也会有一些,只能待后续慢慢优化

后续遗漏的问题

一个就是对现有的项目的代码框架做进一步的熟悉,熟悉各种全局的拓展和宏定义,熟悉masonry框架,对各种UI布局可以快速的实现;熟悉各种性能场景,以及内存泄露场景,目的是写出高质量的代码

ios开发不一样的地方

上手ios开发,会碰到跟其他前端语言很不一样的地方,选几个列取下

方法的调用,需要加中括号

代码语言:javascript复制
[UILabel alloc]

上面的代码,代表执行UILabel类的alloc方法

对变量的声明,需要指定属性特性

代码语言:javascript复制
@property(copy, nonatomic) NSString *name;

代表name的变量,是用复制值的方式setter的,并且不保证线程安全 类型有:assign、atomic、copy、retain、strong、week

每个类都要有.m和.h两个文件,比如page.h和page.m,.h是做声明的,对外部其他类可见,包括变量和方法,.m是具体实现方法的,也包括定义内部变量和方法

控件宽高在布局代码写完后,居然可以直接拿到

代码语言:javascript复制
UILabel *tempLabel = [[UILabel alloc] initWithFrame:CGRectZero];
tempLabel.text = @"asfasfsdafsda";
[tempLabel sizeToFit];
NSLog(@"weigan width %f", tempLabel.width);
 
YGP[11167:4125186] weigan width 106.000000

报错的代码是定位到指针,比较难直接通过报错的log来定位问题

代码语言:javascript复制
023-08-24 11:20:54.219074 0800 YGP[26626:4249029] -[NSNull isEqualToString:]: unrecognized selector sent to instance 0x7ff865b1f580
2023-08-24 11:20:54.261052 0800 YGP[26626:4249029] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSNull isEqualToString:]: unrecognized selector sent to instance 0x7ff865b1f580'
*** First throw call stack:
(
    0   CoreFoundation                      0x00007ff8004288ab __exceptionPreprocess   242
    1   libobjc.A.dylib                     0x00007ff80004dba3 objc_exception_throw   48
    2   CoreFoundation                      0x00007ff800437ab8  [NSObject(NSObject) instanceMethodSignatureForSelector:]   0
    3   CoreFoundation                      0x00007ff80042cd71 ___forwarding___   1431
    4   CoreFoundation                      0x00007ff80042f068 _CF_forwarding_prep_0   120
    5   YGP                                 0x000000010ffbb1f8 __38-[YGPCOMMUniverCellModel isBaiyiButie]_block_invoke   136
    6   CoreFoundation                      0x00007ff80038b4bc __NSARRAY_IS_CALLING_OUT_TO_A_BLOCK__   7
    7   CoreFoundation                      0x00007ff80044a471 -[__NSArrayI enumerateObjectsWithOptions:usingBlock:]   179
    8   YGP                                 0x000000010ffbb0ff -[YGPCOMMUniverCellModel isBaiyiButie]   223
    9   YGP                                 0x0000000110177b8f -[YGPCOMMUniversalCell layoutCellAndComputeHeight:]   223
    10  YGP                                 0x000000010fe60c5c -[YGPCOMMSearchCell layoutCellAndComputeHeight:]   92
    11  YGP                                 0x000000010ff77a20  [YGPSearchCOMMCellLayoutHelper cellHeightWithModel:]   144
    12  YGP                                 0x00000001101415e3 -[YGPCOMMSearchCellModel setCellType:]   83
    13  YGP                                 0x000000011014cb3a __73-[YGPCOMMSearchListVC dealCOMMUnivesalDataWith:tagItemHeight:layoutType:]_block_invoke   490
    14  CoreFoundation                      0x00007ff80038b4bc __NSARRAY_IS_CALLING_OUT_TO_A_BLOCK__   7
    15  CoreFoundation                      0x00007ff800475fbf -[__NSSingleObjectArrayI enumerateObjectsWithOptions:usingBlock:]   80
    16  YGP                                 0x000000011014c88e -[YGPCOMMSearchListVC dealCOMMUnivesalDataWith:tagItemHeight:layoutType:]   1134
    17  YGP                                 0x000000011014cd9a -[YGPCOMMSearchListVC dealSearchProdAndRecommendData:complete:]   522
    18  YGP                                 0x000000011014c0d6 __64-[YGPCOMMSearchListVC configSearchProdWithModel:recommendArray:]_block_invoke.185   742
    19  YGP                                 0x000000011008e62c -[YGPNetworkRequest requestCompleteAndHandleResult:error:complete:]   7324
    20  YGP                                 0x000000011008bf93 __100-[YGPNetworkRequest dataTaskWithHTTPMethod:URLString:parameters:headerParameters:progress:complete:]_block_invoke_2   179
    21  YGP                                 0x000000011035b405 __124-[AFHTTPSessionManager dataTaskWithHTTPMethod:URLString:parameters:headers:uploadProgress:downloadProgress:success:failure:]_block_invoke_2   197
    22  YGP                                 0x000000011037847d __72-[AFURLSessionManagerTaskDelegate URLSession:task:didCompleteWithError:]_block_invoke_2.108   189
    23  libdispatch.dylib                   0x0000000111a80d18 _dispatch_call_block_and_release   12
    24  libdispatch.dylib                   0x0000000111a81f5b _dispatch_client_callout   8
    25  libdispatch.dylib                   0x0000000111a92e5c _dispatch_main_queue_drain   1726
    26  libdispatch.dylib                   0x0000000111a92790 _dispatch_main_queue_callback_4CF   31
    27  CoreFoundation                      0x00007ff800387b1f __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__   9
    28  CoreFoundation                      0x00007ff800382436 __CFRunLoopRun   2482
    29  CoreFoundation                      0x00007ff8003816a7 CFRunLoopRunSpecific   560
    30  GraphicsServices                    0x00007ff809cb128a GSEventRunModal   139
    31  UIKitCore                           0x00000001213b6ad3 -[UIApplication _run]   994
    32  UIKitCore                           0x00000001213bb9ef UIApplicationMain   123
    33  YGP                                 0x000000010fe31a88 main   104
    34  dyld                                0x00000001117762bf start_sim   10
    35  ???                                 0x00000001204c252e 0x0   4836828462
)

一个有点不好看懂的代码(外面的中括号不能拿掉)

代码语言:javascript复制
@property (nonatomic, assign) NSInteger timeInterval;

self.timeInterval = [endDate ? endDate : [NSDate date] timeIntervalSinceDate:[NSDate date]];

block内部有引用self的话,需要带声明,不然会引起泄露(没写也没告警)

代码语言:javascript复制
    @weakify(self);
    [self postListByTypeWithCompletionHandler:^(NSError * _Nullable error, id  _Nullable dataObject) {
        @strongify(self);
        HideHUD(self.view);
        self.tableView.mj_footer.hidden = NO;
        [self resetNoDataView];
        if (!error && dataObject) {
            [self dealSearchCOMMDatas:dataObject];
        } else {
            if (self.dataArrays.count == 0) {
                [self loadNoDataView];
            }
        }
        complete();
    }];

0 人点赞