iOS 编写高质量Objective-C代码(一)

前言:

目前iOS开发主推的官方语言有两种:Objective-C 和 Swift。

今天,小编帮助大家更加熟悉Objective-C,并且聊一聊如何才能编写高质量的OC代码。

一、Objective-C的起源

谈到Objective-C语言的出现,可要比Java还要早十多年。

Java在1995年推出,而Objective-C早在1980年代就已经出现了。

Objective-C (OC)由Smalltalk语言演化而来,后者是消息传递型语言的鼻祖。

  • 消息传递?是的!引入了今天的第一个Key :消息传递。

OC与C++、Java等面向对象语言类似,但又有很大区别。为什么这么说呢?首先要引入的话题就是OC使用消息传递机制,而并非C++、Java使用函数调用机制。

// Objective-C : messaging (消息传递)
Object *obj = [Object new];
[obj performWith:parameter1 and:parameter2];

// C++: function calling(函数调用)
Object *obj = new Object;
obj->perform(parameter1, parameter2);

区别:

  • 消息传递:运行时所执行的代码由运行时环境决定(runtime)

  • 函数调用:运行时所执行的代码由编译器决定

简单来说,OC总在运行时才会去查找真正所要调用的方法,编译器并不用关心接收消息的对象是什么类型,接收消息的对象也是在运行时才工作,其过程叫做动态绑定(dynamic binding)。而其他大部分面向对象语言,会在运行时查找“虚方法表”(virtual table)来查出执行的方法(是调用子类的方法?还是父类的方法?)。

OC是C语言的超集,如果你熟悉C语言,那C语言里的大部分知识在编写OC代码时依然适用。

那么,今天的第二个Key:指针。

OC里的指针主要用来指示对象,基本语法和C语言类似。

例如:声明一个字符串

NSString *str1 = @"QiShare";

语法解释:声明了一个名为str1的变量,其类型为NSString *。是一个指向NSString的指针。

错误案例:

NSString str2;

报错:error:interface type cannot be statically allocated

解释:对象不允许声明在栈空间上

不能在栈中分配OC对象,因为OC对象所占的内存会被分配在堆空间(heap space)上,由程序员来控制它的内存分配。而栈空间的临时基本数据由编译器控制。

再举一个典型案例:

NSString *Qi = @"QiShare";
NSString *Share = Qi;

这里有两个分配在栈空间的NSString指针:Qi和Share指向了堆空间中的同一块内存地址。

内存结构,图解如下:

分配在堆中的对象,内存必须由开发者管理。而分配在栈空间上的指针会在其栈帧弹出时自动清理。

OC将堆内存的管理抽象成了一个机制:ARC(Automatic Reference Counting)。在OC中,不需要用malloc及free来分配或释放对象所占的内存。OC在运行期环境中把这部分工作抽象为一套内存管理架构,我们称之为“引用计数”。之后,我们会有专门的一篇文章讲解ARC机制

二、为了减少编译时间,.h文件中尽量少引入其他头文件。

必要时可以考虑在.h文件里"向前声明"该类。

@class QiShareClass;
@interface xxx : xxx
// ...
@end

在.m文件里再引入该类

#import "QiShareClass.h"
// ....

同时,向前声明也解决了两个类可能存在互相引用的问题。

例如:

  • Qi.h中

#import "Share.h"
  • Share.h中

#import "Qi.h"

当解析"Qi.h"时,编译器发现"Share.h",再导回自己本身"Qi.h"。

从而造成循环引用。这样会导致两个类中有一个类不能正确编译。

推荐:如果用到协议,必要时可以把协议封装在一个单独的头文件里。不仅可以减少编译时间,还能避免循环引用的问题。

三、多用字面量语法,少用等价方法

好处:简明易读,提高代码的可读性和可维护性

局限性:用字面量预防创建数组或字典时,值不能有nil,否则会抛出异常。

For Example:

// 字面量字符串
NSString *str = @"QiShare";

// 字面量数值
NSNumber *num = @(1);
NSNumber *floatNum = @(1.0);
int x = 5;
float y = 3.14;
NSNumber *num = @(x * y);

// 字面量数组
NSArray *animals = @[@"cat", @"dog", @"tiger", @"monkey"];
NSString *cat = animals[0];

// 字面量字典
NSDictionary *qiShareDic = @{@"englishName": @"QiShare",
                             @"chineseName": @"奇分享"}];
NSString *englishName = qiShareDic[@"englishName"];
NSString *chineseName = qiShareDic[@"chineseName"];

注意:用字面量语法创造出来的对象默认都是不可变对象,如果需要可变对象,执行一步 mutableCopy

NSMutableString *mutableStr = [@"QiShare" mutableCopy];

 

四、多用类型常量,少用#define预处理指令

  • 好处:定义出来的常量包含类型信息,不可变,可读性高。

  • 而#define定义的值只是在编译前作字符串替换操作,并不包含类型信息。并且如果一不小心被重新定义了常量值,编译器不会产生任何警告⚠️,最终导致常量值不一致。

For Example:

#define ANIMATION_DURATION 0.5

// 替换成
static const NSTimeInterval kAnimationDuration = 0.5;

// 全局常量
// QiShare.h
extern const NSTimeInterval QiShareAnimationDuration;

// QiShare.m
const NSTimeInterval QiShareAnimationDuration = 0.3;

 

五、多用枚举表示状态、选项、状态码

  • 通过枚举表示状态机的状态、传递给方法的选项以及状态码等值,增强了代码的可读性。

  • 枚举的值如果存在多选的可能,将选项值定义为2的幂。便于底层转成二进制存储。

  • 用NS_ENUM 与 NS_OPTIONS 宏来定义枚举类型可以指明底层的数据类型。由开发者决定,而不是编译器决定。

For Example:

typedef NS_OPTIONS(NSUInteger, UIViewAutoresizing) {
    UIViewAutoresizingNone                 = 0,
    UIViewAutoresizingFlexibleLeftMargin   = 1 << 0,
    UIViewAutoresizingFlexibleWidth        = 1 << 1,
    UIViewAutoresizingFlexibleRightMargin  = 1 << 2,
    UIViewAutoresizingFlexibleTopMargin    = 1 << 3,
    UIViewAutoresizingFlexibleHeight       = 1 << 4,
    UIViewAutoresizingFlexibleBottomMargin = 1 << 5
};

最后,特别致谢《Effective Objective-C 2.0》第一章

作者:MrLiuQ

审校:QiShare团队

链接:https://www.jianshu.com/p/76ac67f1bd95

本文转载自CocoaChina,原文链接http://www.cocoachina.com/ios/20180821/24639.html 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
苹果iOS是由苹果公司开发的手持设备操作系统。苹果公司最早于2007年1月9日的Macworld大会上公布这个系统,最初是设计给iPhone使用的,后来陆续套用到iPod touch、iPad以及Apple TV等苹果产品上。iOS与苹果的Mac OS X操作系统一样,它也是以Darwin为基础的,因此同样属于类Unix的商业操作系统。原本这个系统名为iPhone OS,直到2010年6月7日WWDC大会上宣布改名为iOS。截止至2011年11月,根据Canalys的数据显示,iOS已经占据了全球智能手机系统市场份额的30%,在美国的市场占有率为43%。 源码列表: 按钮类 按钮 Drop Down Control 按钮-Circular Music Player Control 》》Flat Pill Button 按钮类--Fancy Menu 按钮之Custom Gradient Button 按钮之Flat Button 按钮之NIDropDown 按钮之Popup Menu 按钮之UIMenuItem with Image 标签类 标签之Emoji Label 标签之Justifier Label 标签之Top Aligning Label 标签之单一label多颜色多字体 弹出视图 弹出视图 View Bounce Animation 弹出视图(Popup View)UIPopoverListView 弹出视图(Popup View)之URBAlertView 弹出视图(Popup View)之自定义菜单UIMenuBar 弹出视图-Patterned Alert View 弹出视图-Table Alert 弹出视图类--Blur ModalView 弹出视图类--Depth View 弹出视图类--FWTPopover 弹出视图类--icon sheet 弹出视图类--Informatic Toolbar 弹出视图类--WCAlertView 弹出视图之Depth Modal 弹出视图之SelectViewController 导航条 导航条(Navigation Bar)Navigation Menu 导航条(Navigation Bar)之Menu on NavigationBar 导航条类--iOS更换皮肤 导航条之Breadcrumb View 导航条之NavBarNotificationView 导航条之NavigationController Transition 导航条之Title Swipe View 导航条之Title View on NavigationBar 地图类--自定义地图标注 地图(Map)之SJOPaperboy 地图类--Custom Annotation 地图类--DirectionsKit 地图类--Location Indicator 地图类--简单的地图路径 地图类--自定义地图标注 动画类 动画--Spring LoadedView 动画-UIKitForGame 动画类--Guide Arrow 动画之Animation Sequence 动画之Genie Effect 动画之Steam View 分段选择类 分段选择(Segment)之URBSegmentedControl 分段选择类--SVSegmentedControl 扩展 分段选择之AKSegmentedControl 分段选择之Color Bar Segments 滚动视图 滚动的标签 滚动视图(ScrollView)Scroll Grid Controller 滚动视图--Infinite GridView 滚动视图类--CoverFlow 滚动视图类-Lazy ScrollView 滚动视图类--Parallax ScrollView 滚动视图类--Parallax View 滚动视图类-简单的广告栏 滚动视图类--拖动UIScrollView放大图片 滚动视图之Extended UIScrollView 滚动视图之MCPagerView 滚动视图之Page Scrubber Bar 滚动视图之Parallel View 滚动视图之SBFlowView 滚动视图之Wheel Component 汉字转换为拼音 滑竿类 滑杆(Slider)Circular Slider View 滑杆(Slider)之Range Selector 滑杆(Slider)之Volume Bar 滑杆类-Vertical Slider View 滑杆之Slider popover 滑杆之Trim Control 绘图类--My Palette 绘图类--超级简单的画正方形的方法 绘图之Drawing View 基于FMDB的数据库操作 简单阅读器 键盘类 键盘(Keyboard)之自定义表情键盘 键盘-FaceBoard 键盘-Keyboard Bar TextField 键盘类》》Number PadView 键盘类》》ZenKeyboard 键盘类--自定义的拨号键盘 键盘之Custom iOS Keyboard 进图条类 进度条(Progress)Circular Progress View 进度条(Progress)之Progress Toolbar 进度条-Colorful ProgressView 进度条类--Range Slider With Progress 进度条之circular timer 进度条之MCProgressView 开关类 开关(Switch)之RESwitch 开关-Simple Switch Demo 开关之Toggle View 开关之TTSwitch 列表类 联系人搜索算法 列表 纵向Table里嵌套横向Table 列表(Table)Cell Flip Segue 列表(Table)之DynamicHeights 列表(Table)之Expansion Table 列表(Table)之Horizontal table 列表(Table)之Pull Up To Refresh 列表(Table)之TableView with SearchBar 列表(Table)之UITable嵌套UITable 列表(Table)之UploadProgressView 列表-Rainbow Styled Pull To Refresh 列表-UITableView背景随动 列表类》》自定义Table View折叠效果 列表类-FormInputAccessoryView 列表类-Grid TableView 列表类-Grouped TableView With Shadows 列表类--iOS 6.0 Pull to Refresh 列表类--Section Selection View 列表类--Styled TableViewCell 列表类--TableView的各种操作 列表类--UIListView 列表类--下拉刷新加载SQLite数据 列表-让TableView的子view保持固定 列表之ExpansionTableView 列表之iOS Tree Component 列表之Refresh Control 列表之首列固定的列表 日历类 日历(Calendar)之Calendar Picker 日历(Calendar)之TimesSquare 日历之CalendarView 日历控件 日历之封装的My97DatePicker日历 社交类 社交分享-SinaWeibo Share 社交分享类》》ios6 Share Demo 社交分享类--Social Share TableViewCell 社交分享之KRShare 社交分享之MessageActivities 社交分享之ShareSDK 视图布局类 视图布局(View Layout)Border View 视图布局(View Layout)之Linear Layout View 视图布局(View Layout)之Quilt Layout 视图布局(View Layout)之模仿ness伸缩效果 视图布局-Animated Grid 视图布局-Note ViewController 视图布局-Side bar demo 视图布局-Sliding Grid View 视图布局类》》Circle Layout 视图布局类-HGPhoto Wall 视图布局类--Scaling For iPad mini 视图布局类--Swipe ViewController 视图布局之Cycled Viewer 视图布局之Dragging Buttons 视图布局之Mosaic UI 视图布局之Rounded View 视图手势切换 视图切换(View Transition)GuideViewController 视图切换类-3D浏览器 视图切换类--zaker应用进入画面效果 视图切换之视图切换大小渐变效果 手势交互--物体根据重力感应运动 手势交互之Drag View 手势交互之Touch Visualizer 图表类 图表--百分比圆环 图表类--Percentage Chart 图表类--极简个税计算器 图表之Rotation Pie Chart 图表之实时更新的曲线图 图像类 图像(Image)Transition ImageView 图像(Image)之Colorized Progress View 图像-AsyncImageView 图像-Blurred Image 图像-iOS Image Editor 图像-NLImageCropper 图像-Scratch View 图像类 -Photo Zoom 图像类》》360 Degree Panorama 图像类--Before After 图像类--Crop Image 图像类--Image Category 图像类--Image Select and Crop 图像类--OLImageView 图像类View With Bordered Image 图像类--图片下载和保存 图像之AmazeKit 图像之Croppable View 图像之ImagePickerController of InstaPDF 图像之ImageView With Preview 图像之Media Focus Manager 图像之Multiple Image Picker 网络类 网络类--Downloader Management 网络类--photo批量上传ftp 网络类--Reachability 网络之Multi Downloader 文字视图类 文字视图(Text)之AutoComplete TextField 文字视图(Text)之Bar Track ball Item 文字视图(Text)之Messages TableViewController 文字视图(Text)之TextView Placeholder 文字视图-HashTag Mention Controller 文字视图-Tweet Label 文字视图类--Digit Input 文字视图类--emoji-converter 文字视图类--Placeholder TextView 文字视图类--Swipe Shift Caret 文字视图之Autocomplete UITextField 文字视图之Clickable Label 文字视图之Hyperlink Label 文字视图之Note View 文字视图之Rich Content Label 相机类 相机-iOSMp4Camera 相机类>>Camera多张拍摄Demo 相机类--flash light 相机之实用手电筒 选项卡类 选项卡之AKTabBarController 选项卡之Arc Tab 选项卡之LSTabs 选择器类 选择器类--PickerView with Search Bar 选择器类--Value Selector 选择器类--Wheel Menu 选择器类--老虎机 选择器之定制多选的PickerView 音频声效类 音频声效 VoiceTTS Demo 音频声效(Audio)之语音识别 音频声效-iOS Mp3 Recorder 音频声效--VoiceTTS Demo 音频声效类--AAC Audio Converter 音频声效类--BobMusic播放器 音频声效类--Groover 音频声效之Hysteria Player 音频声效之Sound Board 游戏引擎类 游戏引擎(cocos2d)Castle Hassle 游戏引擎类》》模仿合金弹头Demo 游戏引擎类--tank大战 游戏引擎类--Tiny Seal 游戏引擎类--基于cocos2d的连连看游戏 游戏引擎类--简单炸弹人小游戏源码 游戏引擎类--切水果游戏 游戏引擎类幸运大转盘的抽奖游戏 游戏引擎-推箱子游戏 游戏引擎之雷电游戏的激光子弹 指示器类 指示器(HUD)之Android Style Toast 指示器-Activity Bar 指示器--Notify HUD 指示器之MBAlertView 指示器之YLActivityIndicatorView 其他类 财付通打印票据和拖动银行卡效果 寸光阴课程表 功能齐全的计算器 每日金句 扫雷游戏 数字输入 天气预报 之DDClock 之滚动视图旋转菜单 状态栏-StatusBar Notifier View 状态栏之MPNotificationView Ad Controller AdMob demo Animation之Gmail Like Loading AWVersionAgent Bee Framework Circle Menu Cocoa Touch Barcodes Contact Picker FileMD5Hash Fontastic Icons fontawesome Harpy iHasApp In-App Feedback In-App Purchase Inner Shadow Layer Keyboard之DLIDEKeyboard Leak Hunter Message Template NSLogger NSUndoManager Demo Open InApp Activity Passcode Passcode Lock Rating Control SBook ScaffoldKit for Core Data Shine Effect SKYdata Sliding Puzzle Board Spotlight System File Browser Ternary Search Tree UIBezierPath Symbol UITextField 焦点提示 Webview之UIWebView 离线浏览

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值