iOS每日一练(1)---#import,类目和扩展,ARC,类拷贝

1.#import、#include和@class之间的区别

(1)#import和#include:效果相同,只是后者不会引起交叉编译,确保头文件只会被导入一次。
(2)#import和@class:#import包含了这个类的所有信息,包括实体变量和方法。@class告诉编译器,其后面的名称是某个类的名称,它具体的定义暂时不需要知道,后面会告诉你。
PS:
①在.m文件中尽量使用@import(.m文件很可能用到导入文件中的某些方法和变量,所以要清楚的告诉编译器这些内容具体是如何定义和实现的)。
②在.h文件中尽量使用@class,只需要告诉编译器有这个类就可以了。编译效率高
③标准头文件的结构:防止头文件被重复引用

#ifdef __HELLO__
#define __HELLO__
...
#endif

2.类目,类目和类扩展

①类目:(category)
(1)优点:不需要通过增加子类而增加现有类的行为方法,这些方法和原有类没有区别
(2)缺点:无法向类目添加实例变量。覆盖了原始类的方法后,被覆盖的方法无法再使用。(最好不要覆盖)

②类扩展:(extensions)
可以添加属性,且添加的方法是必须要实现的。(extensions)可以认为是一个私有的Category。

4.ARC(自动引用计数)技术和GC(垃圾回收机制)技术

①ARC比GC性能好。且iOS开发只支持MRC和ARC,Mac开发中支持GC,但是在10.8之后弃用了,推荐使用ARC。

ARC的基本介绍
一:创建工程时默认使用ARC,可以在工程选项中(Targets—>Build Phrases—>Compile Sources)选择相应的文件,改变他们对ARC和MRC的选择:
打开ARC:-fobjc-arc
关闭ARC:-fno-objc-arc

二:ARC的修饰符
ARC主要提供了4种修饰符:
①__strong(默认):强引用,所有对象只有当没有任何一个强引用指向时,才会被释放。当需要释放强引用指向的对象时,需要将强引用置nil
②__weak:只要对象没有任何强引用指向,即使有再多的弱引用指向也没用,该对象依然会被释放。当该对象被释放时,指向它的弱引用都会被置为nil,可以防止无效指针、野指针的产生。(PS:一般使用在delegate关系中防止循环引用,或者用来修饰由Interface Builder编辑与生成的UI控件)
③__autoreleasing:在autorelease pool中自动释放对象的引用。(比较复杂,暂不细说)
④__unsafe_unretained:弃用

PS:以上4种修饰符的使用很多人存在“错误”
习惯写法(错误):
__weak NSString *str = @"hello";
正确写法:
NSString *__weak str = @"hello";
苹果公司知道很多人会写错,所以让编译器忽略了这个错误并且内部做了修改,但是还是建议写成正确的形式

ARC中存在内存泄露,例如:ARC中也会循环引用导致内存泄露,OC对象与CoreFoundation类之间桥接时,管理不当也会产生内存泄露

5.深、浅复制,对象拷贝

①对象拷贝:copy和mutableCopy方法的区别,这种区别只在于那些有可变对象和不可变对象之分的对象上,而对没有这种区别的对象来说都只是拷贝而已。
a)不可变对象浅拷贝:
新对象 = [不可变对象 copy] ===> 新对象 = [不可变对象 retain];
PS:新对象==不可变对象(即指向同一个对象),两者的retainCount=2。而对可变对象的copy都会产生新的retainCount

b)不可变对象深拷贝:
新对象 = [不可变对象 mutableCopy];(拷贝不可变对象时,推荐这样拷贝。这样,新的对象的属性成员与原对象无关)
PS:新对象!=不可变对象,两者的retainCount都为1

②浅复制:只复制对象本身,不复制属性。即新对象和旧对象共用属性(即内部的属性的retainCount为2)
深复制:不仅复制对象本身,对象持有的属性对象也做复制(即内部的属性的retainCount各为1)

总结:
简单的来说就是,在有指针的情况下,浅拷贝只是增加了一个指针指向已经存在的内存,而深拷贝就是增加一个指针并且申请一个新的内存,使这个增加的指针指向这个新的内存,采用深拷贝的情况下,释放内存的时候就不会出现在浅拷贝时重复释放同一内存的错误

PS:当某个类需要具有可拷贝属性时,需要签订和协议,并实现里面的copyingWithZone方法。例如:

#import <Foundation/Foundation.h>

@interface Person : NSObject<NSCopying,NSMutableCopying>
@property(nonatomic,copy) NSString* name;
@property(nonatomic,retain) NSNumber* age;

@end

#import "Person.h"
@implementation Person

- (id)copyWithZone:(NSZone *)zone{
    Person *person=[[[self class]allocWithZone:zone]init]; 
    //深拷贝,_name是NSString,不可变对象
    person.name = [_name mutableCopy];

    //浅拷贝,直接赋值 
    person.age=_age;  
    return person;
}

@end

6.用户自定义了一个对象,如何实现拷贝(可变和不可变)

必须实现copying和mutableCopying协议,表示返回一个不可变和可变对象,否则程序出现异常。

7.定义属性时,什么时候使用assign、strong、copy、nonatomic

(1)assign:普通赋值。一般用于基本数据模型,常见于委托设计模式,以此来防止循环引用
(2)strong:获得了对象的所有权。引用计数+1
(3)copy:一般字符串使用copy
(4)nonatomic:非原子性访问。在多线程并发访问过程中可以提高性能

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值