• 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 保留重复值

  • 相关阅读:
    delete
    js混淆代码还原-js反混淆:利用js进行赋值实现
    Microservice Trade-Offs
    tagged by: microservices 【martinfowler.com】
    Tackle Business Complexity in a Microservice with DDD and CQRS Patterns
    Why Can't I Access A Protected Member From A Derived Class
    tagged by: domain driven design 【martinfowler.com】
    Domain Driven Design
    Why Would I Ever Need to Use C# Nested Classes
    RabbitMQ compare with redis and MSMQ
  • 原文地址:https://www.cnblogs.com/machao/p/5216037.html
Copyright © 2020-2023  润新知