内存管理
1.写一个setter方法用于完成@property (nonatomic,retain)* NSString *name,
写一个setter方法用于完成@property(nonatomic,copy)NSString *name
1>@property(nonatomic,retain)NSString *name; -(void)setName:(NSString *)name { if(_name != name){ [_name release]; _name = [name retain]; } 2>@property(nonatomic, copy)NSString *name; -(void)setName:(NSString *)name { if(_name != name){ [_name release]; _name = [name copy]; } }
2,#import 跟#include、@class有什么区别?#import<> 跟 #import””又什么区别?
1> #import和#include都能完整地包含某个文件的内容,#import能防止同一个文件被包含多次 2> @class仅仅是声明一个类名,并不会包含类的完整声明;@class还能解决循环包含的问题 3> #import <> 用来包含系统自带的文件,#import “”用来包含自定义的文件
3,属性readwrite,readonly,assign,retain,copy,nonatomic 各是什么作用,在那种情况下用?
1> readwrite:同时生成get方法和set方法的声明和实现 2> readonly:只生成get方法的声明和实现 3> assign:set方法的实现是直接赋值,用于基本数据类型 4> retain:set方法的实现是release旧值,retain新值,用于OC对象类型 5> copy:set方法的实现是release旧值,copy新值,用于NSString、block等类型 6> nonatomic:非原子性,set方法的实现不加锁(比atomic性能高
4,@property 后面可以有哪些修饰符?
线程安全的: atomic,nonatomic 访问权限的 readonly,readwrite 内存管理(ARC) assign,strong,weak,copy 内存管理(MRC) assign,retain,copy 指定方法名称 setter= getter=
5 什么情况使用 weak 关键字,相比 assign 有什么不同?比如:
在ARC中,出现循环引用的时候,必须要有一端使用weak,比如:自定义View的代理属性 已经自身已经对它进行一次强应用,没有必要在强引用一次,此时也会使用weak,自定义View的子控件属性一般也使用weak;但b是也可以使用strong weak当对象销毁的时候,指针会被自动设置为nil,而assign不会* assigin 可以用非OC对象,而weak必须用于OC对象
怎么用 copy 关键字?
1,对于字符串和block的属性一般使用copy 2,字符串使用copy是为了防止外部把字符串内容改了,影响该属性 (NSString、NSArray、NSDictionary 等等经常使用copy关键字,是因为他们有对应的可变类型:NSMutableString、NSMutableArray、NSMutableDictionary;他们之间可能进行赋值操作,为确保对象中的字符串值不会无意间变动,应该在设置新属性值时拷贝一份) 3,block使用copy是在MRC遗留下来的,在MRC中,方法内部的block是在在栈区的,使用copy可以把它放到堆区.在ACR中对于block使用copy还是strong效果是一样的 (但写上 copy 也无伤大雅,还能时刻提醒我们:编译器自动对 block 进行了 copy 操作。如果不写 copy ,该类的调用者有可能会忘记或者根本不知道“编译器会自动对 block 进行了 copy 操作”,他们有可能会在调用之前自行拷贝属性值。这种操作多余而低效)
这个写法会出什么问题: @property (copy) NSMutableArray *array;
两个问题: 1、添加,删除,修改数组内的元素的时候,程序会因为找不到对应的方法而崩溃.因为 copy 就是复制一个不可变 NSArray 的对象; 2、使用了 atomic 属性会严重影响性能
如何让自己的类用 copy 修饰符?如何重写带 copy 关键字的 setter?
具体步骤: 1.需声明该类遵从 NSCopying 协议 2.实现 NSCopying 协议。该协议只有一个方法:- (id)copyWithZone:(NSZone *)zone;
用@property声明的NSString(或NSArray,NSDictionary)经常使用copy关键字,为什么?如果改用strong关键字,可能造成什么问题?
1.因为父类指针可以指向子类对象,使用 copy 的目的是为了让本对象的属性不受外界影响,使用 copy 无论给我传入是一个可变对象还是不可对象,我本身持有的就是一个不可变的副本. 2.如果我们使用是 strong ,那么这个属性就有可能指向一个可变对象,如果这个可变对象在外部被修改了,那么会影响该属性.
assign 与 weak
assign是指针赋值,不对引用计数操作,使用之后如果没有置为nil,可能就会产生野指针;而weak一旦不进行使用后,永远不会使用了,就不会产生野指针! weak更安全 避免循环引用
@protocol 和 category 中如何使用 @property
在protocol中使用property只会生成setter和getter方法声明,我们使用属性的目的,是希望遵守我协议的对象的实现该属性 category 使用 @property 也是只会生成setter和getter方法的声明,如果我们真的需要给category增加属性的实现,需要借助于运行时的两个函数 objc_setAssociatedObject objc_getAssociatedObject
weak属性需要在dealloc中置nil么?
不需要,在ARC环境无论是强指针还是弱指针都无需在deallco设置为nil,ARC会自动帮我们处理
ARC下,不显示指定任何属性关键字时,默认的关键字都有哪些?
对应基本数据类型默认关键字是 atomic,readwrite,assign 对于普通的OC对象 atomic,readwrite,strong
在有了自动合成属性实例变量之后,@synthesize还有哪些使用场景?
@synthesize主要就是用来生成setter,getter方法的实现,在@property被增强之后,其实已经很少使用@synthesize了,你知道@synthesize的其他使用场景吗? 能给我介绍一下吗? 如果你听懂了,感觉面试官说的很有道理,可以说点赞美的话
objc中向一个对象发送消息[obj foo]和objc_msgSend()函数之间有什么关系?
该方法编译之后就是objc_msgSend()函数调用.如果我没有记错的大概是这样的. ((void ()(id, SEL))(void )objc_msgSend)((id)obj, sel_registerName("foo"));
一个objc对象如何进行内存布局?(考虑有父类的情况)
所有父类的成员变量和自己的成员变量都会存放在该对象所对应的存储空间中. 每一个对象内部都一个isA指针,指向他的类对象,类对象中存放着本对象的对象方法列表和成员变量的列表,属性列表,它内部也有一个isA指针指向元对象(meta class),元对象内部存放的是类方法列表,类对象内部还有一个superclass的指针,指向他的父类对象 根对象就是NSobject 一个objc对象的isa的指针指向什么?有什么作用? 指向他的类对象,从而可以找到对象上的方法
下面的代码输出什么?
@implementation Son : Father
- (id)init
{
self = [super init];
if (self) {
NSLog(@"%@", NSStringFromClass([self class]));
NSLog(@"%@", NSStringFromClass([super class]));
}
return self;
}
@end
输出的结果都是:Son,
原因:super 和 self 都是指向的本实例对象的,
不同的是,super调用的跳过本类方法,调用父类的方法
父类方法的class方法本来都是在基类中实现的,所以无论使用self和super调用都是一样的.
objc中的类方法和实例方法有什么本质区别和联系?
类方法 类方法是属于类对象的 类方法只能通过类对象调用 类方法中的self是类对象 类方法可以调用其他的类方法 类方法中不能访问成员变量 类方法中不定直接调用对象方法 实例方法 实例方法是属于实例对象的 实例方法只能通过实例对象调用 实例方法中的self是实例对象 实例方法中可以访问成员变量 实例方法中直接调用实例方法 实例方法中也可以调用类方法(通过类名)
_objc_msgForward函数是做什么的,直接调用它将会发生什么?
runtime如何实现weak变量的自动置nil?
没哟研究过,从名字来看是用来转发消息的,你能给我讲讲吗?谢谢! 1. 没有研究过,你有研究过吗,可以给我讲讲吗? 2. 我猜系统会维护一个弱指针列表,当某个对象销毁时候,它会把所有指向该对象的弱指针设置为nil
runloop和线程有什么关系?
1. 每一个线程中都一个runloop,只有主线的的runloop默认是开启的,其他线程的runloop是默认没有开启的 2. 可以通过CFRunLoopRun() 函数来开启一个事件循环 3. 看SDWebImage源码的时候见到有这么用过.
runloop的mode作用是什么?
model 主要是用来指定时间在运行循环中的优先级的 苹果公开提供的 Mode 有两个: kCFRunLoopDefaultMode kCFRunLoopCommonModes 如果我们把一个NSTimer对象以kCFRunLoopDefaultMode添加到主运行循环中的时候,当一直有用户事件处理的时候,NSTimer将不再被调度 如果我们把一个NSTimer对象以kCFRunLoopCommonModes添加到主运行循环中的时候,当一直有用户事件处理的时候,NSTimer还能正常的调度,互不影响.
以+ scheduledTimerWithTimeInterval…的方式触发的timer,在滑动页面上的列表时,timer会暂定回调,为什么* ?如何解决? 同上
猜想runloop内部是如何实现的?
1. 他是一个死循环 2.如果事件队列中存放在事件,那就取出事件,执行相关代码 3.如果没有事件,就挂起,等有事件了,立即唤醒事件循环,开始执行. 简单来说。。。 function loop() { initialize(); do { var message = get_next_message(); process_message(message); } while (message != quit); }
不手动指定autoreleasepool的前提下,一个autorealese对象在什么时刻释放?(比如在一个vc的viewDidLoad中创建
在每次事件循环开始创建自动释放池,在每次事件结束销毁自动释放池 以viewDidLoad方法为例,可以理解为在viewDidLoad方法开始执行之前创建自动释放池, 在viewDidLoad方法执行之后销毁自动释放
BAD_ACCESS在什么情况下出现?
1. 死循环了 2. 访问一个僵尸对象
苹果是如何实现autoreleasepool的?
1. 我猜想autoreleasepool 本质就是一个队列(数组), 2. 当调用autorelease的时候会把该对象添加到autoreleasepool中,并且把引用计数+1 3. 当autoreleasepool即将销毁的时候,把其中的所有对象进行一次release操作
如何调试BAD_ACCESS错误
lldb(gdb)常用的调试命令?
1.设置全局断点快速定位问题代码所在行 最常用就是 : po 对象
Objective-C如何对内存管理的,说说你的看法和解决方法?
1> 每个对象都有一个引用计数器,每个新对象的计数器是1,当对象的计数器减为0时,就会被销毁 2> 通过retain可以让对象的计数器+1、release可以让对象的计数器-1 3> 还可以通过autorelease pool管理内存 4> 如果用ARC,编译器会自动生成管理内存的代码
What is advantage of categories? What is difference between implementing a category and extensions?
1> 分类是有名称的,类扩展没有名称
2> 分类只能扩充方法、不能扩充成员变量;类扩展可以扩充方法和成员变量
3> 类扩展一般就写在.m文件中,用来扩充私有的方法和成员变量(属性category和extensions的不同在于 后者可以添加属性。另外后者添加的方法是必须要实现的。 extensions可以认为是一个私有的Category。
2.What is advantage of categories? What is difference between implementing a category and inheritance? 类别的作用?继承和类别在实现中有何区别?
category 可以在不获悉,不改变原来代码的情况下往里面添加新的方法,只能添加,不能删除修改。 并且如果类别和原来类中的方法产生名称冲突,则类别将覆盖原来的方法,因为类别具有更高的优先级。 类别主要有3个作用: (1)将类的实现分散到多个不同文件或多个不同框架中。 (2)创建对私有方法的前向引用。 (3)向对象添加非正式协议。 继承可以增加,修改或者删除方法,并且可以增加属性
When we call objective c is runtime language what does it mean? 我们说的obc是动态运行时语言是什么意思
答案:多态。 主要是将数据类型的确定由编译时,推迟到了运行时。 这个问题其实浅涉及到两个概念,运行时和多态。 简单来说,运行时机制使我们直到运行时才去决定一个对象的类别,以及调用该类别对象指定方法。 多态:不同对象以自己的方式响应相同的消息的能力叫做多态。意思就是假设生物类(life)都用有一个相同的方法-eat; 那人类属于生物,猪也属于生物,都继承了life后,实现各自的eat,但是调用是我们只需调用各自的eat方法。 也就是不同的对象以自己的方式响应了相同的消息(响应了eat这个选择器)。 因此也可以说,运行时机制是多态的基础?
Object-C有多继承吗?没有的话用什么代替?
1> OC是单继承,没有多继承 2> 有时可以用分类和协议来代替多继承
Object-C有私有方法吗?私有变量呢
1> OC没有类似@private的修饰词来修饰方法,只要写在.h文件中,就是公共方法 2> 可以使用类扩展(Extension)来增加私有方法和私有变量
关键字const什么含义
const int a;
int const a;
const int *a;
int const *a;
int * const a;
int const * const a;
1> 前两个的作用是一样:a 是一个常整型数
2> 第三、四个意味着 a 是一个指向常整型数的指针(整型数是不可修改的,但指针可以)
3> 第五个的意思:a 是一个指向整型数的常指针(指针指向的整型数是可以修改的,但指针是不可修改的)
4> 最后一个意味着:a 是一个指向常整型数的常指针(指针指向的整型数是不可修改的,同时指针也是不可修改的)
static的作用?
1> static修饰的函数是一个内部函数,只能在本文件中调用,其他文件不能调用 2> static修饰的全部变量是一个内部变量,只能在本文件中使用,其他文件不能使用 3> static修饰的局部变量只会初始化一次,并且在程序退出时才会回收内存
堆和栈的区别?
1> 堆空间的内存是动态分配的,一般存放对象,并且需要手动释放内存 2> 栈空间的内存由系统自动分配,一般存放局部变量等,不需要手动管理内存
为什么很多内置的类,如TableView的delegate的属性是assign(weak)不是retain(strong)?
1> tableView的代理一般都是它所属的控制器,控制器会对它内部的view做一次retain操作 2> 假设tableView也对代理(控制器)做一次retain操作,那么就出现循环retain问题
定义属性时,什么情况使用copy、assign、retain?
1> copy:NSString、Block等类型 2> assign:非OC对象类型, 基本数据类型(两个对象相互引用的时候,一端用retain, 一端用assign) 3> retain:OC对象类型
对象是什么时候被释放的?
每个对象都有一个引用计数器,每个新对象的计数器是1,当对象的计数器减为0时,就会被销 毁
如何对iOS设备进行性能测试
Timer Profile
obj-c的优缺点
objc优点: 1) Cateogies 2) Posing 3) 动态识别 4) 指标计算 5)弹性讯息传递 6) 不是一个过度复杂的 C 衍生语言 7) Objective-C 与 C++ 可混合编程
缺点: 1) 不支援命名空間 2) 不支持运算符重载
3) 不支持多重继承
4) 使用动态运行时类型,所有的方法都是函数调用,所以很多编译时优化方法都用不到。(如内联函数等),性能低劣ARC下还会存在内存泄露吗? 循环引用会导致内存泄露
Objective-C对象与CoreFoundation对象进行桥接的时候如果管理不当也会造成内存泄露 CoreFoundation中的对象不受ARC管理,需要开发者手动释放