当前位置:首页 > 科技数码 > 正文

iOS开发语言Objective C —知识点总结(2)

摘要: iOS开发语言ObjectiveC—知识点总结(2)最佳答案53678位专家为你答疑解惑iOS开发语言ObjectiveC—知识...

iOS开发语言Objective C —知识点总结(2)

最佳答案 53678位专家为你答疑解惑

iOS开发语言Objective C —知识点总结(2)

内存管理

什么是堆?什么是栈?

答:栈(操作系统):由操作系统自动分配释放,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈(先进后出);???????????????????????????????????????????????????????????????????????????????????? 堆(操作系统):一般由程序员分配释放,若程序员不释放,程序结束时可能由系统回收,分配方式类似于链表。

什么是内存管理?

答:所谓内存管理, 就是对内存进行管理, 涉及的操作有:

分配内存 : 比如创建一个对象, 会增加内存占用

清除内存 : 比如销毁一个对象, 能减小内存占用

内存管理的本质是什么?

答:OC对象存放于堆里面 ;非OC对象一般放在栈里面(栈内存会被系统自动回收)

MRC内存管理

什么是引用计数器?

答:每个OC对象都有自己的引用计数器,它是一个整数,表示有多少人正在用这个对象

引用计数器的作用?

答:(1)当使用alloc、new或者copy创建一个对象时,对象的引用计数器默认就是1;

(2)当对象的引用计数器为0时,对象占用的内存就会被系统回收;

如果对象的计数器不为0,那么在整个程序运行过程,它占用的内存就不可能被回收(除非整个程序已经退出 )

怎么操作引用计数器?

答:给对象发送一条retain消息,可以使引用计数器值+1(retain方法返回对象本身);

给对象发送一条release消息, 可以使引用计数器值-1;

给对象发送retainCount消息, 可以获得当前的引用计数器值。

需要注意的是: release并不代表销毁\回收对象, 仅仅是计数器-1。

dealloc 方法的作用?

答:对象即将被销毁时系统会自动给对象发送一条dealloc消息 (因此, 从dealloc方法有没有被调用,就可以判断出对象是否被销毁)

重写dealloc方法有什么注意点?

答:重写dealloc方法, [super dealloc]一定要写到所有代码的最后

内存管理的原则?

答:(1)谁创建谁release :如果你通过alloc、new、copy或mutableCopy来创建一个对象,那么你必须调用release或autorelease;(2)谁retain谁release:只要你调用了retain,就必须调用一次release;(3)循环引用,一边用retain一边用assign。

autorelease 自动释放池

1.什么是自动释放池?

答: autorelease是一种支持引用计数的内存管理方式,只要给对象发送一条autorelease消息,会将对象放到一个自动释放池中,当自动释放池被销毁时,会对池子里面的所有对象做一次release操作

2.自动释放池的优点是什么?

答: 不用再关心对象释放的时间,不用再关心什么时候调用release

3.简述自动释放池的原理?

答: autorelease实际上只是把对release的调用延迟了,对于每一个autorelease,系统只是把该 Object放入了当前的autorelease pool中,当该pool被释放时,该pool中的所有Object会被调用Release。

4.自动释放池有哪些注意事项?

答: (1)在自动释放池中创建了对象, 一定要调用autorelease,才会将对象放入自动释放池中

(2)一个程序中可以创建N个自动释放池, 并且自动释放池还可以嵌套

(3)不要再自动释放池中使用比较消耗内存的对象, 占用内存比较大的对象

(4)尽量不要再自动释放池中使用循环, 特别是循环的次数非常多, 并且还非常占用内存

(5)千万不要写多次autorelease

(6)一个alloc/new对应一个autorelease或者release

5.自动释放池是以什么形式存储的?

答: 如果存在多个自动释放池的时候, 自动释放池是以 “栈” 的形式存储在堆区

栈的特点: 先进后出

ARC内存管理

1:ARC的原理是什么?

答:当ARC开启时,编译器将自动在代码合适的地方插入retain, release和autorelease,而作为程序猿,完全不需要担心编译器会做错(除非开发者自己错用ARC了)。

ARC有什么优点?

答: 1.完全消除了手动管理内存的烦琐, 让程序猿更加专注于app的业务

2.基本上能够避免内存泄露

3.有时还能更加快速,因为编译器还可以执行某些优化

ARC的原则是什么?什么是强指针?什么是弱指针?

答:只要还有一个强指针变量指向对象,对象就会保持在内存中

(1)强指针 :默认所有指针变量都是强指针 ,被__strong修饰的指针

(2)弱指针 :被__weak修饰的指针

ARC下@property修饰符有哪些?

答: strong : 用于OC对象, 相当于MRC中的retain

weak : 用于OC对象, 相当于MRC中的assign

assign : 用于基本数据类型, 跟MRC中的assign一样

ARC中是怎么对对象进行内存管理的?

答: (1)ARC下单对象内存管理

(2)ARC下,所有的指针都是强指针

(3)ARC, A对象想拥有B对象, 那么就需要用一个强指针指向B对象

(4)A对象不用B对象了, 什么都不需要做, 编译器会自动帮我们做

ARC怎么解决循环引用问题?

答: ARC和MRC一样, 如果A拥有B, B也拥有A, 那么必须一方使用弱指针

也就是说 一端用strong ,一端用weak

类别 Category

1.类别的作用

答:有时我们需要在一个已经定义好的类中增加一些方法,而不想去重写该类。可以使用类别对该类扩充新的方法。

注意:类别只能扩充方法,而不能扩充成员变量。

2.Category的作用?

答:(1)在不改变原来的类内容的基础上,为类增加一些方法。

(2)一个庞大的类可以分模块开发,由多个人来编写,更有利于团队合作

3.分类,原来类或者父类中的方法调用的顺序?

答:先调用分类中的方法(最后参与编译的分类优先),再调用原来类中的方法,最后掉用父类中的方法

匿名扩展Extension

1.什么是类扩展?

答:延展类别又称为扩展(Extension),Extension是Category的一个特例

2.类扩展格式?

答:类扩展书写格式

@interface 类名 ()

@end

3.类扩展的作用是什么?

答:写在.m文件中,可以为某个类扩充一些私有的成员变量和方法

Block

什么是Block?

答:Block是iOS中一种比较特殊的数据类型,用来保存某一段代码

Block的作用?

答:Block用来保存某一段代码, 可以在恰当的时间再取出来调用

功能类似于函数和方法

Block的格式?

答:Block的格式:

返回值类型 (^block变量名)(形参列表)=^(形参列表) {

};

Block对变量的用法

在block块内部:1.局部变量相当于一个常量,其值不可更改;2.静态局部变量的值可以修改:3.全局变量的值也可以更改。

如果在代码块内部需要对局部变量进行赋值操作,可以在局部变量定义时使用__block来修饰

__block int b1=1000;

void (^MYblock1)(void)=^{

b1++;

NSLog(@"b1=%d",b1);

int b2=11+b1;

NSLog(@"b2=%d",b2);

};

MYblock1();//1001,1012

b1++;

MYblock1();//1003 1014

协议

1.什么是协议?

答:其他语言有接口的概念,接口就是一堆方法的声明没有实现.

OC中没有接口的概念,OC中的接口就是协议.

协议Protocol是由一系列的方法声明组成的

2.书写协议的格式?

答:格式:

@protocol 协议名称

// 方法声明列表

@end

3.一个类怎么遵循协议?

答:格式:

@interface 类名 : 父类 <协议名称1, 协议名称2,…>

@end

注意:

(1)一个类可以遵守1个或多个协议

(2)任何类只要遵守了Protocol,就相当于拥有了Protocol的所有方法声明

4.协议和继承有什么区别?

答:?(1)继承之后默认就有实现, 而protocol只有声明没有实现

(2)相同类型的类可以使用继承, 但是不同类型的类只能使用protocol

(3)protocol可以用于存储方法的声明, 可以将多个类中共同的方法抽取出来, 以后让这些类遵守协议即可

5.什么是基协议?

答:基协议:是基协议,是最根本最基本的协议,其中声明了很多最基本的方法。

注意:建议每个新的协议都要遵守NSObject协议

6.协议有哪些注意事项?

答:?(1)协议只能声明方法, 不能声明属性

(2)父类遵守了某个协议, 那么子类也会自动遵守这个协议

(3)在OC中一个类可以遵守1个或多个协议

注意: OC中的类只能有一个父类, 也就是说OC只有单继承

(4)OC中的协议又可以遵守其它协议, 只要一个协议遵守了其它协议, 那么这个协议中就会自动包含其它协议的声明

7.协议中控制方法的能否实现的关键字是什么?各有什么作用?

(1)注意: 如果没有使用任何关键字修饰协议中的方法, 那么该方法默认就是required的

(2)注意:@required和@optional仅仅使用程序员之间交流, 并不能严格的控制某一个遵守该协议的类必须要实现该方法, 因为即便不是实现也不会报错, 只会报一个警告

(3)?@required ?:如果协议中的方法是@required的, 要求遵守协议的类实现@required所修饰的方法,如果没有实现该方法, 那么会报一个警告

(4)?@optional ?:如果协议中的方法是@optional的, 遵守协议的类可选择实现@optional所修饰的方法,如果没有实现该方法, 那么不会报警告

代理

1.代理模式的应用场景?

答:(1)当A对象想监听B对象的一些变化时, 可以使用代理设计模式

(2)当B对象发生一些事情, 想通知A对象的时候, 可以使用代理设计模式

(3)当对象A无法处理某些行为的时候,想让对象B帮忙处理(让对象B成为对象A的代理对象)

2.用什么类型来接收遵守协议的代理对象?

答:使用id类型接收代理对象

3.简述一下协议的编写规范?

答:(1)一般情况下, 当前协议属于谁, 我们就将协议定义到谁的头文件中

(2)协议的名称一般以它属于的那个类的类名开头, 后面跟上protocol或者delegate

(3)协议中的方法名称一般以协议的名称protocol之前的作为开头

(4)一般情况下协议中的方法会将触发该协议的对象传递出去

4.一般情况下一个类中的代理属于的名称叫做 delegate

5.当某一个类要成为另外一个类的代理的时候,一般情况下在.h中用@protocol 协议名称;告诉当前类 这是一个协议。在.m中用#import真正的导入一个协议的声明

6.委托代理(degegate),目的是改变和传递控制链

Copy

1.使用copy功能的前提是什么?

答: 使用copy前提:需要遵守NSCopying协议,实现copyWithZone:方法

使用mutableCopy的前提:需要遵守NSMutableCopying协议,实现mutableCopyWithZone:方法

2.如何使用copy功能?

答:?一个对象可以调用copy或mutableCopy方法来创建一个副本对象

copy : 创建的是不可变副本(如NSString、NSArray、NSDictionary)

mutableCopy :创建的是可变副本(如NSMutableString、NSMutableArray、NSMutableDictionary)

3.copy基本原则?

答:?修改源对象的属性和行为,不会影响副本对象

修改副本对象的属性和行为,不会影响源对象

4.为什么通过不可变对象调用了copy方法, 不会生成一个新的对象?

答:?因为原来的对象是不能修改的, 拷贝出来的对象也是不能修改的

既然两个都不能修改, 所以永远不能影响到另外一个对象, 那么已经符合需求

所以: OC为了对内存进行优化, 就不会生成一个新的对象

5.自定义类如何实现copy操作?

答:(1)以后想让自定义的对象能够被copy只需要遵守NSCopying协议

(2)实现协议中的- (id)copyWithZone:(NSZone *)zone

(3)在- (id)copyWithZone:(NSZone *)zone方法中创建一个副本对象, 然后将当前对象的值赋值给副本对象即可

copy内存管理

1.浅复制(浅拷贝,指针拷贝,shallow copy)

源对象和副本对象是同一个对象

源对象(副本对象)引用计数器+1,相当于做一次retain操作

本质是:没有产生新的对象

2.深复制(深拷贝,内容拷贝,deep copy)

源对象和副本对象是不同的两个对象

源对象引用计数器不变,副本对象计数器为1(因为是新产生的)

本质是:产生了新的对象

单例

1.什么是单例模式?

答:类的对象成为系统中唯一的实例,提供一个访问点,供客户类 共享资源

单例就是无论怎么创建都只能有一个实例对象

2.什么情况下使用单例?

答:(1)类只能有一个实例,而且必须从一个为人熟知的访问点对其进行访问,比如工厂方法。

(2)这个唯一的实例只能通过子类化进行扩展,而且扩展的对象不会破坏客户端代码。

3.创建单例对象的方法一般以什么开头?

答:(1)一般情况下创建一个单利对象都有一个与之对应的类方法

(2)一般情况下用于创建单利对象的方法名称都以share开头, 或者以default开头

Objective-C编码规范:26个方面解决iOS开发问题

【按语】由于我正在准备模拟开发饿了么这个App,到时可能有些iOS开发者参与进来。这时如果每个人的Objective-C编码风格都不一样,这样不易于保持代码一致性和难以Code Review。所以我在网上搜索到The official raywenderlich.com Objective-C style guide这篇关于Objective-C编码风格的文章,觉得可以作为这个项目的Objective-C的编码标准,所以就翻译这篇文章。这篇编码风格指南概括了raywenderlich.com的编码规范,可能有些删减或修改。

介绍

我们制定Objective-C编码规范的原因是我们能够在我们的书,教程和初学者工具包的代码保持优雅和一致。即使我们有很多不同的作者来完成不同的书籍。

这里编码规范有可能与你看到的其他Objective-C编码规范不同,因为它主要是为了打印和Web的易读性。

关于作者

我们也非常感谢New York Times 和Robots & Pencils'Objective-C编码规范的作者。这两个编码规范为本指南的创建提供很好的起点。

背景

这里有些关于编码风格Apple官方文档,如果有些东西没有提及,可以在以下文档来查找更多细节:

语言

应该使用US英语。

应该:

UIColor *myColor=[UIColor whiteColor];

不应该:

UIColor *myColour=[UIColor whiteColor];

代码组织

在函数分组和protocol/delegate实现中使用#pragma mark -来分类方法,要遵循以下一般结构:

#pragma mark - Lifecycle- (instancetype)init {}- (void)dealloc {}- (void)viewDidLoad {}- (void)viewWillAppear:(BOOL)animated {}- (void)didReceiveMemoryWarning {}#pragma mark - Custom Accessors- (void)setCustomProperty:(id)value {}- (id)customProperty {}#pragma mark - IBActions- (IBAction)submitData:(id)sender {}#pragma mark - Public- (void)publicMethod {}#pragma mark - Private- (void)privateMethod {}#pragma mark - Protocol conformance#pragma mark - UITextFieldDelegate#pragma mark - UITableViewDataSource#pragma mark - UITableViewDelegate#pragma mark - NSCopying- (id)copyWithZone:(NSZone *)zone {}#pragma mark - NSObject- (NSString *)description {}

空格缩进使用4个空格,确保在Xcode偏好设置来设置。(raywenderlich.com使用2个空格)方法大括号和其他大括号(if/else/switch/while 等.)总是在同一行语句打开但在新行中关闭。

应该:

if (user.isHappy) {    //Do something} else {    //Do something else}

不应该:

if (user.isHappy){  //Do something}else {  //Do something else}
在方法之间应该有且只有一行,这样有利于在视觉上更清晰和更易于组织。在方法内的空白应该分离功能,但通常都抽离出来成为一个新方法。优先使用auto-synthesis。但如果有必要,@synthesize和@dynamic应该在实现中每个都声明新的一行。应该避免以冒号对齐的方式来调用方法。因为有时方法签名可能有3个以上的冒号和冒号对齐会使代码更加易读。请不要这样做,尽管冒号对齐的方法包含代码块,因为Xcode的对齐方式令它难以辨认。

应该:

// blocks are easily readable[UIView animateWithDuration:1.0 animations:^{  // something} completion:^(BOOL finished) {  // something}];

不应该:

// colon-aligning makes the block indentation hard to read[UIView animateWithDuration:1.0                 animations:^{                     // something                 }                 completion:^(BOOL finished) {                     // something                 }];

注释

当需要注释时,注释应该用来解释这段特殊代码为什么要这样做。任何被使用的注释都必须保持最新或被删除。

一般都避免使用块注释,因为代码尽可能做到自解释,只有当断断续续或几行代码时才需要注释。例外:这不应用在生成文档的注释

命名

Apple命名规则尽可能坚持,特别是与这些相关的memory management rules(NARC)。

长的,描述性的方法和变量命名是好的。

应该:

UIButton *settingsButton;

不应该:

UIButton *setBut;

三个字符前缀应该经常用在类和常量命名,但在Core Data的实体名中应被忽略。对于官方的raywenderlich.com书、初学者工具包或教程,前缀'RWT'应该被使用。

常量应该使用驼峰式命名规则,所有的单词首字母大写和加上与类名有关的前缀。

应该:

static NSTimeInterval const RWTTutorialViewControllerNavigationFadeAnimationDuration=0.3;

不应该:

static NSTimeInterval const fadetime=1.7;

属性也是使用驼峰式,但首单词的首字母小写。对属性使用auto-synthesis,而不是手动编写@synthesize语句,除非你有一个好的理由。

应该:

@property (strong, nonatomic) NSString *descriptiveVariableName;

不应该:

id varnm;

上一篇:PVC吸塑片材

下一篇:DOTA2怎么更新不了

发表评论