IOS 开发中要注意的事项

1.关于拍摄

  • TGCameraViewController – 基于 AVFoundation 的自定义相机。样式漂亮,轻量并且可以很容易地集成到 iOS 项目中。不会内存吃紧

2.block 中对控制器本身的self方法的调用一定要改成weak 属性

3.在使用tabbarController 的时候一定要使用自定义的控制器,中间的tabbar最好也是自定义的

4.MVVMReactiveCocoa     重要 这个是框架问题

5.在使用字符串的时候考虑控件的大小和语言,

举例:

desc = [QKYStringHelper localStringNamed:@"实签合同"];

self.backMoneyLabel.text = [NSString stringWithFormat:@"%@%d%%(¥%@)",desc,trueRate1,[MachaoTool getNumberFormatByNumerString:trueA]];

 6.在使用XLForm 时候要自定义组标题的内容可以使用

viewForHeaderInSection

覆盖之前titleForHeaderInSection

这个需要拼接很多参数,如果有固定的写死的,也要分开来,在前边单独定义一个属性,这个方便应用的国际化

7.开发swift中可是用

ObjectMapper 字典转模型,

之所以使用swift的,是因为swift中的基本数据类型和oc的有所区别,如果用oc的字典转模型,会有写类型转不过来,比方说 Int 类型的 ,NSDate 类型的

8.ios 开发文件分类体系:

AppDelegate
Models
Macro
General
Helpers
Vendors
Sections
Resources

一个合理的目录结构首先应该是清晰的,让人一眼看上去就能大概了解目录的职责,且容易应对新的变化。

AppDelegate

这个目录下放的是AppDelegate.h(.m)文件,是整个应用的入口文件,所以单独拿出来。

Models

这个目录下放一些与数据相关的Model文件,里面大概是这样:

Models
    |- BaseModel.h
    |- BaseModel.m
    |- CollectionModel.h
    |- CollectionModel.m
    ...

Macro

这个目录下放了整个应用会用到的宏定义,里面大概是这样:

Macro
    |- AppMacro.h
    |- NotificationMacro.h
    |- VendorMacro.h
    |- UtilsMacro.h
    ...

AppMacro.h 里放app相关的宏定义,如:

// 表情相关
#define EMOTION_CACHE_PATH @"cachedemotions"
#define EMOTION_RECENT_USED @"recentusedemotions"
#define EMOTION_CATEGORIES @"categoryemotions"
#define EMOTION_TOPICS @"emotiontopics"

// 收藏相关
#define COLLECT_CACHE_PATH @"collected"

// 配图相关
#define WATERFALL_ITEM_HEIGHT_MAX 300
#define WATERFALL_ITEM_WIDTH 146

NotificationMacro.h 里放的是通知相关的宏定义。

UtilsMacro.h 里放的是一些方便使用的宏定义,如:

#define UIColorFromRGB(r,g,b) [UIColor 
colorWithRed:r/255.0 
green:g/255.0 
blue:b/255.0 alpha:1]

#define NSStringFromInt(intValue) [NSString stringWithFormat:@"%d",intValue]

VendorMacro.h 里放一些第三方常量,如:

#define UMENG_KEY @"xxxxx"
#define UMENG_CHANNEL_ID @"xxx"

如果有新的类型的宏定义,可以再新建一个相关的Macro.h。

General

这个目录放会被重用的Views/Classes和Categories。里面大概是这样:

General
    |- Views
        |- TPKScollView
        |- TPKPullToRefresh
        ...
    |- Classes
        |- TPKBaseViewController
        |- TPKHorizontalView
        ...
    | - Categories
        |- UIViewController+Sizzle
        |- UIImageView+Downloader
        ...

这里的TPK是项目的首字母缩写。

Helpers

这个目录放一些助手类,文件名与功能挂钩。里面大概是这样:

Helpers
    |- TPKShareHelper
    |- TPDBHelper
    |- TPKEmotionHelper
    ...

助手类的主要作用是帮助Controller瘦身,也可以提供一定程度的复用。

Vendors

这个目录放第三方的类库/SDK,如UMeng、WeiboSDK、WeixinSDK等等。

Sections

这个目录下面的文件对应的是app的具体单元,如导航、瀑布流等等。里面大概是这样:

Sections
    |- Menu
    |- Setting
    |- Collection
    ...

Resources

这个目录下放的是app会用到的一些资源,主要是图片。

9.在对页面进行布局的情况加不适用 自动布局 ,采用SDAutoLayout ,这个是基于不同位置的库, 

10.在swift开发中,经常要用到tableviewcontroller ,为了增加程序的扩展性,应该使用泛型来定义数据类型和cell类型,

这样可以方便在后续中进行扩展,使用例子https://github.com/agelessman/ConfigurableTableViewController.git

11.写一个网络请求的basic类来封装网络请求,目的是在更换网络框架的时候很方便,把全局的请求参数都放到基类中添加,可以在每次发请求之前都对当前的网络情况进行判断,然后通过block进行返回

12 . 当我们使用系统的对象不能满足我们需求的情况,通常我们采取集成系统控件,从写他的某个方法

几个例子: 

NSNumberFormatter  如果我们需要19:00 这样的数字, 系统是满足不了的, 我们可以重写他的内部方法

- (NSString *)stringFromNumber:(NSNumber *)number

 13. 在对图像的处理,图像和视频的捕获中 使用GPUImage 进行处理

14. 在平时的开发中,使用到的所有的权限相关的东西 比如AVFoundation 中的摄像头和麦克风中的权限,需要一个统一的方法进行设置,然后接受一个error 参数,代码如下

1 - (void)setupSessionWithError:(NSError **)error
2 {
3 }

然后在控制器中根据这个错误指针 给用户提示

 15. iOS平台有哪些WebSocket和Socket的开源框架

Socket开源框架有:CocoaAsyncSocketsocketio/socket.io-client-swift

WebSocket开源框架有:facebook/SocketRockettidwall/SwiftWebSocket

 16. swift 开发中 使用delegate 的时候,要设置为weak 属性,不然不能释放

17. swift 写的api 中的类使用public 修饰,否则oc 不能访问

18. 在开发中 接口文件最好能再次封装到一个或多个类中,这样加入日后有点模块需要单独做成静态库的话,就会很方便

19.总体来说,但凡是需要反复使用的东西,尽量做缓存操作,这应该算是一种思想吧

20. 写一个app的网络接口的URL 获取类, 专门获取 每一个请求的URL,所有的请求 也可以写到一个配置文件中,使用block 传递参数,之所以不分散到每个DataController 中,是为了减少代码的重复,除非有父子关系的控制器 可以在DataController 中 包含儿子的DataController,为的就是解耦,在接口配置文件中 不需要的接口 要及时标注,

举例说明: 比方说 有一个可获取行业的控制器A,写了一个DataController 获取行业数据,现在又有了一个新的控制器B,里边有别的业务,但是也需要获取行业数据,按照平时 可能在这个新的控制器的DataController 拥有 行业控制器A的DataController 然后获取数据就行了 ,但是,如果,以后的业务用不到这个A 的时候, 但是B要存在, 就不能删除A,这就是上边解释的 耦合性的问题。

21. AVFoundation  视频播放有一个缓存播放的功能没有加,这个需要研究HTTPServer 后,加入这个功能 ,有很多任务需要完成,感觉时间不够用,

在解读完YYModel 后,研究HTTPServer 源代码,

22.在swift 中如果有一个对象必须遵守某一个或多个协议的写法是这样的

override func httpResponseForMethod(method: String!, URI path: String!) -> protocol<NSObjectProtocol, HTTPResponse>!

- (NSObject<HTTPResponse> *)httpResponseForMethod:(NSString *)method URI:(NSString *)path

 23. 在开发中设计到对网络的封装应该假想成SDk这样的模式,业务成调用网络接口应该像调用framework一样,根本不知道URL和内部细节,具体实现是应该通过一个Client类来输出所有的网络请求

24. __Require_Quiet 类似这样宏的使用

导入头文件#import <AssertMacros.h>

可以看出,通过调用这个宏可以跳转到代码的某个地方,_out 是一个标记,如果条件为空,就会跳到我们打标记的地方。

__Require_noErr_Quiet  如果发生异常,就跳转到标记的地方

25. 关于开发中函数的函数的使用问题

当一个字段能够标示好几种情况时,我们就应该考虑使用枚举进行封装

比如iscontain 这个字段 0代表不能加载 1代表可以加载 2代表已添加  3代表已过期

我们封装成枚举是这样的

typedef NS_ENUM(NSUInteger, MyAppStatus) {
    MyAppStatusDisable,
    MyAppStatusEnable,
    MyAppStatusAdded,
    MyAppStatusExpired,
};
@property (nonatomic,copy)NSString *iscontain;
@property (nonatomic,assign,readonly)MyAppStatus appStatus;

因为是只读的,实现getter方法

- (MyAppStatus)appStatus {
    
    // 根据iscontain这个资环获取app状态
    // 0代表不能加载 1代表可以加载 2代表已添加  3代表已过期
    switch (self.iscontain.integerValue) {
        case 1:
            return MyAppStatusEnable;
            break;
        case 2:
            return MyAppStatusAdded;
            break;
        case 3:
            return MyAppStatusExpired;
            break;
        default:
            return MyAppStatusDisable;
            break;
    }
}

在使用中我们写一个函数,有点类似c中的函数,则也算是一种思想,可以理解为私有函数,这样把他们方法一个文件的头部,更加容易查看

// 根据状态获取要显示的字符串
static NSString * getButtonStrWithAppStatus(MyAppStatus status) {
    
    NSString *str;
    
    switch (status) {
        case MyAppStatusEnable:
            str = [QKYStringHelper localStringNamed:@"Add"];
            break;
        case MyAppStatusAdded:
            str = [QKYStringHelper localStringNamed:@"Added"];
            break;
        case MyAppStatusExpired:
            str = [QKYStringHelper localStringNamed:@"Expired"];
            break;
        default:
            str = [QKYStringHelper localStringNamed:@"Unauthorized"];
            break;
    }
    
    return str;
}
_buttonStr = getButtonStrWithAppStatus(app.appStatus);

 26.

tasks = [@[dataTasks, uploadTasks, downloadTasks] valueForKeyPath:@"@unionOfArrays.self"];
这么使用之前确实不太知道,如果是我,可能就直接赋值给数组了。那么`@unionOfArrays.self`又是什么意思呢?

* @distinctUnionOfObjects 清楚重复值
* unionOfObjects 保留重复值

原文地址:https://www.cnblogs.com/machao/p/5216037.html