美文网首页
iOS (2) --OC语言

iOS (2) --OC语言

作者: iLees | 来源:发表于2016-11-11 22:25 被阅读35次

    <h1>1、Difference between method and selector(方法和选择器有何不同)?</h1>selector是一个方法的名字,method是一个组合体,包含了名字和实现.

    <h1>2、Core Foundation的内存管理</h1> 凡是带有Create、Copy、Retain等字眼的函数,创建出来的对象,都需要在最后做一次release 比如CFRunLoopObserverCreate release函数:CFRelease(对象);

    <h1>3、你是否接触过OC中的反射机制?简单聊一下概念和使用</h1> 1> class反射
    a、通过类名的字符串形式实例化对象
    Class class NSClassFromString@(@"student");
    Student *stu = [[class alloc ]init];
    b、将类名变为字符串
    Class class =[Student class];
    NSString className = NSStringFromClass(class);
    2> SEL的反射
    a、通过方法的字符串形式实例化方法
    SEL selector = NSSelectorFromClass(@"setName");
    [stu performSelector:selector withObject:@"Mike"];
    b、将方法变成字符串
    NSStringFomrSelector(@selector
    (setName:))

    <h1>4、协议中<NSObject>是什么意思?子类继承了父类,那么子类会遵守父类中遵守的协议吗?协议中能够定义成员变量?如何约束一个对象类型的变量要存储的地址是遵守一个协议对象?</h1> 遵守NSObject协议

    能,但是只在头文件中声明,编译器是不会自动生成实例变量的。需要自己处理getter和setter方法
    id<xxx>

    <h1>5、我们说的Objective-C是动态运行时语言是什么意思? (When we call objective c is runtime language what does it mean?)</h1> 主要是将数据类型的确定由编译时,推迟到了运行时。这个问题其实浅涉及到两个概念,运行时和多态。
    1> 简单来说, 运行时机制使我们直到运行时才去决定一个对象的类别,以及调用该类别对象指定方法。
    2>多态:不同对象以自己的方式响应相同的消息的能力叫做多态。
    意思就是假设生物类(life)都拥有一个相同的方法-eat;那人类属于生物,猪也属于生物,都继承了life后,实现各自的eat,但是调用是我们只需调用各自的eat方法。也就是不同的对象以自己的方式响应了相同的消 息(响应了eat这个选择器)。因此也可以说,运行时机制是多态的基础.

    <h1>6、简述NotificationCenter、KVC、KVO、Delegate?并说明它们之间的区别?(重点)</h1>

     KVO(Key-Value- Observing):一对多, 观察者模式,键值观察机制,它提供了观察某一属性变化的方法,极大简化了代码。
    
    KVC(Key-Value-Coding):是键值编码, 一个对象在调用setValue的时候,检查是否存在相应key的set方法,存在就调用set方法。
    set方法不存在,就查找_key的成员变量是否存在,存在就直接赋值。
    如果_key没找到,就查找相同名称的key,存在就赋值。如果没有就调用valueForUndefinedkey和setValue:forUndefinedKey。
    
    Delegate: 通常发送者和接收者的关系是直接的一对一的关系。代理的目的是改变或传递控制链。
    允许一个类在某些特定时刻通知到其他类,而不需要获取到那些类的指针。可以减少框架复杂度。
    消息的发送者(sender)告知接收者(receiver)某个事件将要发生,delegate同意然然后发送者响应事件,
    delegate机制使得接收者可以改变发送者的行为。
    
    Notification: 观察者模式, 通常发送者和接收者的关系是间接的多对多关系。
    消息的发送者告知接收者事件已经发生或者将要发送,仅此而已,接收者并不能反过来影响发送者的行为。
    

    由上可知区别如下:

    1> 效率肯定是delegate比NSNotification高。
    2> delegate方法比notification更加直接,需要关注返回值,所以delegate方法往往包含should这个很传神的词。相反的,notification最大的特色就是不关心结果。所以notification往往用did这个词汇。
    两个模块之间联系不是很紧密,就用notification传值,例如多线程之间传值用notificaiton。
    delegate只是一种较为简单的回调,且主要用在一个模块中,例如底层功能完成了,需要把一些值传到上层去,就事先把上层的函数通过delegate传到底层,然后在底层call这个delegate,它们都在一个模块中,完成一个功能,例如说 NavgationController 从 B 界面到A 点返回按钮 (调用popViewController方法) 可以用delegate比较好。

    <h1>7、OC有多继承吗?没有的话可以用什么方法替代?</h1> 多继承即一个子类可以有多个父类,它继承了多个父类的特性。
    Object-c的类没有多继承,只支持单继承,如果要实现多继承的话,可以通过类别和协议的方式来实现。
    1> protocol(协议)可以实现多个接口,通过实现多个接口可以完成多继承;
    2> Category(类别)一般使用分类,用Category去重写类的方法,仅对本Category有效,不会影响到其他类与原有类的关系。

    <h1>8、分别描述类别(categories)和延展(extensions)是什么?以及两者的区别?继承和类别在实现中有何区别?为什么Category只能为对象添加方法,却不能添加成员变量?</h1> 类别: 在没有原类.m文件的基础上,给该类添加方法;
    延展: 一种特殊形式的类别,主要在一个类的.m文件里声明和实现延展的作用,就是给某类添加私有方法或是私有变量。
    两个的区别:
    1> 延展可以添加属性并且它添加的方法是必须要实现的。延展可以认为是一个私有的类目。
    类别可以在不知道,不改变原来代码的情况下往里面添加新的方法,只能添加,不能删除修改。
    并且如果类别和原来类中的方法产生名称冲突,则类别将覆盖原来的方法,因为类别具有更高的优先级。
    继承可以增加,修改删除方法,添加属性。
    Category只能为对象添加方法,却不能添加成员变量的原因:如果可以添加成员变量,添加的成员变量没有办法初始化

    <h1>9、include与#import的区别? #import与@class的区别?</h1> import指令是Object-C针对#include的改进版本,#import确保引用的文件只会被引用一次,这样你就不会陷入递归包含的问题中。

    import与@class二者的区别在于:
    1> import会链入该头文件的全部信息,包括实例变量和方法等;而@class只是告诉编译器,其后面声明的名称是类的名称,至于这些类是如何定义的,暂时不用考虑。
    2> 在头文件中一般使用@class来声明这个名称是类的名称,不需要知道其内部的实体变量和方法.
    而在实现类里面,因为会用到这个引用类的内部的实体变量和方法,所以需要使用#import来包含这个被引用类的头文件。
    3> 在编译效率方面,如果你有100个头文件都#import了同一个头文件,或者这些文件是依次引用的,如A–>B, B–>C, C–>D这样的引用关系。当最开始的那个头文件有变化的话,后面所有引用它的类都需要重新编译,如果你的类有很多的话,这将耗费大量的时间。而是用@class则不会。
    4> 如果有循环依赖关系,如:A–>B, B–>A这样的相互依赖关系,如果使用#import来相互包含,那么就会出现编译错误,如果使用@class在两个类的头文件中相互声明,则不会有编译错误出现。

    <h1>10、浅复制(拷贝)和深复制的区别? (Difference between shallow copy and deep copy?)</h1> 浅复制(copy):只复制指向对象的指针,而不复制引用对象本身。
    深复制(mutableCopy):复制引用对象本身。深复制就好理解了,内存中存在了两份独立对象本身, 当修改A时,A_copy不变。

    <h1>11、类变量的@protected,@private,@public,@package声明各有什么含义?</h1> 变量的作用域不同。

    @protected 该类和子类中访问,是默认的;
    @private 只能在本类中访问;
    @public 任何地方都能访问;
    @package 本包内使用,跨包不可以

    <h1>12、Objective-C与C、C+++之间的联系和区别?</h1> 1> Objective-C和C++都是C的面向对象的超集。
    2> Object与C++的区别主要点:Objective-C是完全动态的,支持在运行时动态类型决议(dynamic typing),动态绑定(dynamic binding)以及动态装载(dynamic loading);而C++是部分动态的,编译时静态绑定,通过嵌入类(多重继承)和虚函数(虚表)来模拟实现。
    3> Objective-C 在语言层次上支持动态消息转发,其消息发送语法为 [object function]; 而且C++ 为 object->function()。 两者的语义也不同,在 Objective-C 里是说发送消息到一个对象上,至于这个对象能不能响应消息以及是响应还是转发消息都不会 crash; 而在 C++ 里是说对象进行了某个操作,如果对象没有这个操作的话,要么编译会报错(静态绑定),要么程序会 crash 掉的(动态绑定)。

    <h1>13、目标-动作机制</h1> 1> 目标是动作消息的接收者。一个控件,或者更为常见的是它的单元,以插座变量的形式保有其动作消息的目标。
    2>动作是控件发送给目标的消息,或者从目标的角度看,它是目标为了响应动作而实现的方法. 程序需要某些机制来进行事件和指令的翻译。这个机制就是目标-动作机制。

    <h1>14、Objective-C优点和缺点</h1> 优点:1.Cateogies 2.Posing 3.动态识别 4.指标计算 5.弹性讯息传递 6.不是一个过度复杂的C衍生语言 7.Objective-C与C++可混合编程

    缺点:1.不支持命名空間 2.不支持运算符重载 3.不支持多重继承 4.使用动态运行时类型,所有的方法都是函数调用,所以很多编译时优化方法都用不到。(如内联函数等),性能低劣。

    <h1>15、C与OC混用</h1> 处理.m可以识别c和oc,.mm可以识别c c++ oc 但是cpp只能用c/c++

    <h1>16、atomic和nonatomic的区别</h1> atomic提供多线程安全,防止读写未完成的时候被另外一个线程读写,造成数据错误。
    nonatomic在自己管理内存的环境中,解析的访问器保留并自动释放返回值,若指定了nonatomic,那么访问器只是简单的返回这个值。

    <h1>17、常见的oc数据类型哪些,和c的基本类型有啥区别</h1> 常见的:NSInteger CGFloat NSString NSNumber NSArray NSDate
    NSInteger根据32或者64位系统决定本身是int还是long
    CGFloat根据32或者64位系统决定本身是float还是double
    NSString NSNumber NSArray NSDate都是指针类型的对象,在堆中分配内存,c语言中的char int 等都是在栈中分配空间

    <h1>18、id和nil代表什么</h1> id类型的指针可以指向任何OC对象
    nil代表空值(空指针的值,0)

    <h1>19、nil、Nil、NULL和NSNull区别?</h1> 1> nil和C语言的NULL相同,在objc/objc.h中定义。nil表示Objective-C对象的值为空。在C语言中,指针的空值用NULL表示。在Objective-C中,nil对象调用任何方法表示什么也不执行,也不会崩溃。
    2> Nil:那么对于我们Objective-C开发来说,Nil也就代表((void )0)。但是它是用于代表空类的. 比如:Class myClass = Nil;
    3> NULL: 在C语言中,NULL是无类型的,只是一个宏,它代表空. 这就是在C/C++中的空指针。对于我们Objective-C开发来说,NULL就表示((void
    )0).
    NSNull:NSNull是继承于NSObject的类型。它是很特殊的类,它表示是空,什么也不存储,但是它却是对象,只是一个占位对象。使用场景就不一样了,比如说服务端接口中让我们在值为空时,传空。NSDictionry *parameters = @{@"arg1" : @"value1",@"arg2" : arg2.isEmpty ? [NSNull null] : arg2};

    4> NULL、nil、Nil这三者对于Objective-C中值是一样的,都是(void *)0,那么为什么要区分呢?又与NSNull之间有什么区别:

    5> NULL是宏,是对于C语言指针而使用的,表示空指针
    6> nil是宏,是对于Objective-C中的对象而使用的,表示对象为空
    7> Nil是宏,是对于Objective-C中的类而使用的,表示类指向空
    8> NSNull是类类型,是用于表示空的占位对象,与JS或者服务端的null类似的含意

    <h1>20、向一个nil对象发送消息会发生什么?</h1> 1> 向nil发送消息是完全有效的——只是在运行时不会有任何作用。
    2> 如果一个方法返回值是一个对象,那么发送给nil的消息将返回0(nil)
    3> 如果方法返回值为指针类型,其指针大小为小于或者等于sizeof(void*),float,double,long double 或者long long的整型标量,发送给nil的消息将返回0。
    4> 如果方法返回值为结构体,正如在《Mac OS X ABI 函数调用指南》,发送给nil的消息将返回0。结构体中各个字段的值将都是0。其他的结构体数据类型将不是用0填充的。
    5> 如果方法的返回值不是上述提到的几种情况,那么发送给nil的消息的返回值将是未定义的

    <h1>21、self.和self->的区别</h1> 1> self.是调用get或者set方法
    2> self是当前本身,是一个指向当前对象的指针
    3> self->是直接访问成员变量

    <h1>22、_block/weak修饰符区别</h1> 1> _block在arc和mrc环境下都能用,可以修饰对象,也能修饰基本数据类型
    2> _weak只能在arc环境下使用,只能修饰对象(NSString),不能修饰基本数据类型(int)
    3> _block对象可以在block中重新赋值,_weak不行。

    <h1>23、@property的本质是什么?ivar、getter、setter是如何生成并添加到这个类中的?</h1>

    @property的本质:
    @property = ivar(实例变量) + getter(取方法) + setter(存方法)
    “属性” (property)有两大概念:ivar(实例变量)、存取方法(access method = getter + setter)
    ivar、getter、setter如何生成并添加到类中:
    这是编译器自动合成的,通过@synthesize关键字指定,若不指定,默认为@synthesize propertyName = _propertyName;
    若手动实现了getter/setter方法,则不会自动合成。
    现在编译器已经默认为我们添加@synthesize propertyName = _propertyName;因此不再需要手动添加了,除非你真的要改成员变量名。
    生成getter方法时,会判断当前属性名是否有_,比如声明属性为@property (nonatomic, copy) NSString *_name;
    那么所生成的成员变量名就会变成__name,如果我们要手动生成getter方法,就要判断是否以_开头了。
    不过,命名都要有规范,是不允许声明属性是使用_开头的,不规范的命名,在使用runtime时,会带来很多的不方便的。
    

    <h1>24、这个写法会出什么问题:@property (copy) NSMutableArray *array;</h1> 1> 没有指明为nonatomic,因此就是atomic原子操作,会影响性能。该属性使用了同步锁,会在创建时生成一些额外的代码用于帮助编写多线程程序,这会带来性能问题,通过声明nonatomic可以节省这些虽然很小但是不必要额外开销。在我们的应用程序中,几乎都是使用nonatomic来声明的,因为使用atomic并不能保证绝对的线程安全,对于要绝对保证线程安全的操作,还需要使用更高级的方式来处理,比如NSSpinLock、@syncronized等
    2> 因为使用的是copy,所得到的实际是NSArray类型,它是不可变的,若在使用中使用了增、删、改操作,则会crash

    <h1>25、@protocol和category中如何使用 @property</h1>

    在protocol中使用@property只会生成setter和getter方法声明,我们使用属性的目的是希望遵守我协议的对象能实现该属性
    •    category使用@property也是只会生成setter和getter方法的声明,如果我们真的需要给category增加属性的实现,需要借助于运行时的两个函数:
    •    objc_setAssociatedObject
    •    objc_getAssociatedObject
    

    <h1>26、@property中有哪些属性关键字?</h1> 1> 原子性 (atomic,nonatomic)
    2> 读写(readwrite, readonly)
    3> 内存管理(assign, strong, weak, unsafe_unretained,copy)
    4> getter、setter

    <h1>27、isa指针问题</h1> isa:是一个Class 类型的指针. 每个实例对象有个isa的指针,他指向对象的类,而Class里也有个isa的指针, 指向meteClass(元类)。元类保存了类方法的列表。当类方法被调用时,先会从本身查找类方法的实现,如果没有,元类会向他父类查找该方法。同时注意的是:元类(meteClass)也是类,它也是对象。元类也有isa指针,它的isa指针最终指向的是一个根元类(root meteClass).根元类的isa指针指向本身,这样形成了一个封闭的内循环。

    <h1>28、如何访问并修改一个类的私有属性?</h1> 一种是通过KVC获取
    通过runtime访问并修改私有属性

    <h1>29、如何为 Class 定义一个对外只读对内可读写的属性?</h1> 在头文件中将属性定义为readonly,在.m文件中将属性重新定义为readwrite

    <h1>30、Objective-C 中,meta-class 指的是什么?</h1> meta-class 是 Class 对象的类,为这个Class类存储类方法,当一个类发送消息时,就去这个类对应的meta-class中查找那个消息,每个Class都有不同的meta-class,所有的meta-class都使用基类的meta-class(假如类继承NSObject,那么他所对应的meta-class也是NSObject)作为他们的类

    <h1>31、Objective-C 的class是如何实现的?Selector是如何被转化为 C 语言的函数调用的?</h1>

    1>当一个类被正确的编译过后,在这个编译成功的类里面,存在一个变量用于保存这个类的信息。我们可以通过[NSClassFromString]或[obj class]。这样的机制允许我们在程序执行的过程当中,可以Class来得到对象的类,也可以在程序执行的阶段动态的生成一个在编译阶段无法确定的一个对象。 (isa指针)
    2> @selector()基本可以等同C语言的中函数指针,只不过C语言中,可以把函数名直接赋给一个函数指针,而Object-C的类不能直接应用函数指针,这样只能做一个@selector语法来取.

    @interface foo
    -(int)add:int val;
    @end
    SEL class_func ; //定义一个类方法指针
    class_func = @selector(add:int);
    

    3> @selector是查找当前类的方法,而[object @selector(方法名:方法参数..) ] ;是取object对应类的相应方法.
    查找类方法时,除了方法名,方法参数也查询条件之一.
    可以用字符串来找方法 SEL 变量名 = NSSelectorFromString(方法名字的字符串);
    可以运行中用SEL变量反向查出方法名字字符串。NSString *变量名 = NSStringFromSelector(SEL参数);

    4> 取到selector的值以后,执行seletor。 SEL变量的执行.用performSelecor方法来执行.
    [对象 performSelector:SEL变量 withObject:参数1 withObject:参数2];

    <h1>32、对于语句NSString *obj = [[NSData alloc] init]; ,编译时和运行时obj分别是什么类型?</h1> 编译时是NSString类型 ,运行时是NSData类型.

    <h1>33、@synthesize和@dynamic分别有什么作用?</h1> 1> @property有两个对应的词,一个是 @synthesize,一个是 @dynamic。如果 @synthesize和 @dynamic都没写,那么默认的就是@syntheszie var = _var;
    2> @synthesize 的语义是如果你没有手动实现 setter 方法和 getter 方法,那么编译器会自动为你加上这两个方法。
    3> @dynamic 告诉编译器:属性的 setter 与 getter 方法由用户自己实现,不自动生成。(当然对于 readonly 的属性只需提供 getter 即可)。假如一个属性被声明为 @dynamic var,然后你没有提供 @setter方法和 @getter 方法,编译的时候没问题,但是当程序运行到 instance.var = someVar,由于缺 setter 方法会导致程序崩溃;或者当运行到 someVar = var 时,由于缺 getter 方法同样会导致崩溃。编译时没问题,运行时才执行相应的方法,这就是所谓的动态绑定。

    <h1>34、NSString 的时候用copy和strong的区别?</h1> OC中NSString为不可变字符串的时候,用copy和strong都是只分配一次内存,但是如果用copy的时候,需要先判断字符串是否是不可变字符串,如果是不可变字符串,就不再分配空间,如果是可变字符串才分配空间。如果程序中用到NSString的地方特别多,每一次都要先进行判断就会耗费性能,影响用户体验,用strong就不会再进行判断,所以,不可变字符串可以直接用strong。

    <h1>35、NSArray、NSSet、NSDictionary与NSMutableArray、NSMutableSet、NSMutableDictionary的特性和作用(遇到copy修饰产生的变化)</h1> 特性:
    NSArray表示不可变数组,是有序元素集,只能存储对象类型,可通过索引直接访问元素,而且元素类型可以不一样,但是不能进行增、删、改操作;NSMutableArray是可变数组,能进行增、删、改操作。通过索引查询值很快,但是插入、删除等效率很低。
    NSSet表示不可变集合,具有确定性、互异性、无序性的特点,只能访问而不能修改集合;NSMutableSet表示可变集合,可以对集合进行增、删、改操作。集合通过值查询很快,插入、删除操作极快。
    NSDictionary表示不可变字典,具有无序性的特点,每个key对应的值是唯一的,可通过key直接获取值;NSMutableDictionary表示可变字典,能对字典进行增、删、改操作。通过key查询值、插入、删除值都很快。
    <h1></h1>
    作用:
    数组用于处理一组有序的数据集,比如常用的列表的dataSource要求有序,可通过索引直接访问,效率高。
    集合要求具有确定性、互异性、无序性,在iOS开发中是比较少使用到的,笔者也不清楚如何说明其作用
    字典是键值对数据集,操作字典效率极高,时间复杂度为常量,但是值是无序的。在ios中,常见的JSON转字典,字典转模型就是其中一种应用。

    <h1>36、怎样使用performSelector传入3个以上参数,其中一个为结构体</h1>

    - (id)performSelector:(SEL)aSelector;
    - (id)performSelector:(SEL)aSelector withObject:(id)object;
    - (id)performSelector:(SEL)aSelector withObject:(id)object1 withObject:(id)object2;
    

    因为系统提供的performSelector的api中,并没有提供三个参数。因此,我们只能传数组或者字典,但是数组或者字典只有存入对象类型,而结构体并不是对象类型,那么怎么办呢?
    没有办法,我们只能通过对象放入结构作为属性来传过去了:

    ypedef struct HYBStruct {
      int a;
      int b;
    } *my_struct;
    
    @interface HYBObject : NSObject
    
    @property (nonatomic, assign) my_struct arg3;
    @property (nonatomic, copy)  NSString *arg1;
    @property (nonatomic, copy) NSString *arg2;
    
    @end
    
    @implementation HYBObject
    
    // 在堆上分配的内存,我们要手动释放掉
    - (void)dealloc {
      free(self.arg3);
    }
    
    @end
    
    

    测试:

    my_struct str = (my_struct)(malloc(sizeof(my_struct)));
    str->a = 1;
    str->b = 2;
    HYBObject *obj = [[HYBObject alloc] init];
    obj.arg1 = @"arg1";
    obj.arg2 = @"arg2";
    obj.arg3 = str;
    
    [self performSelector:@selector(call:) withObject:obj];
    
    // 在回调时得到正确的数据的
    - (void)call:(HYBObject *)obj {
        NSLog(@"%d %d", obj.arg3->a, obj.arg3->b);
    }
    

    <h1>37、objc中向一个对象发送消息[obj foo]和objc_msgSend()函数之间有什么关系?</h1> 实际上,编译器在编译时会转换成objc_msgSend,大概会像这样:
    ((void (*)(id, SEL))(void)objc_msgSend)((id)obj, sel_registerName("foo"));
    也就是说,[obj foo];在objc动态编译时,会被转换为:objc_msgSend(obj, @selector(foo));这样的形式,但是需要根据具体的参数类型及返回值类型进行相应的类型转换。

    <h1>38、下面的代码输出什么?</h1>

    @implementation Son : Father
    
    - (id)init {
        self = [super init];
        if (self) {
            NSLog(@"%@", NSStringFromClass([self class]));
            NSLog(@"%@", NSStringFromClass([super class]));
        }
        return self;
    }
    
    @end
    
    // 输出
    NSStringFromClass([self class]) = Son
    NSStringFromClass([super class]) = Son
    这个题目主要是考察关于Objective-C中对self和super的理解。我们都知道:self是类的隐藏参数,指向当前调用方法的这个类的实例。那super呢?
    很多人会想当然的认为“super和self类似,应该是指向父类的指针吧!”。这是很普遍的一个误区。
    其实 super是一个 Magic Keyword,它本质是一个编译器标示符,和self 是指向的同一个消息接受者!
    他们两个的不同点在于:super会告诉编译器,调用class 这个方法时,要去父类的方法,而不是本类里的。
    上面的例子不管调用[self class]还是[super class],接受消息的对象都是当前 Son *xxx 这个对象。
    当使用self调用方法时,会从当前类的方法列表中开始找,如果没有,就从父类中再找;
    而当使用super时,则从父类的方法列表中开始找。然后调用父类的这个方法。
    

    <h1>39、若一个类有实例变量NSString *_foo,调用setValue:forKey:时,可以以foo还是_foo作为key?</h1> 两者都可以。

    <h1>40、什么时候使用NSMutableArray,什么时候使用NSArray?</h1> 当数组在程序运行时,需要不断变化的,使用NSMutableArray,当数组在初始化后,便不再改变的,使用NSArray。需要指出的是,使用NSArray只表明的是该数组在运行时不发生改变,即不能往NSAarry的数组里新增和删除元素,但不表明其数组內的元素的内容不能发生改变。NSArray是线程安全的,NSMutableArray不是线程安全的,多线程使用到NSMutableArray需要注意。

    <h1>41、类NSObject的那些方法经常被使用?</h1> NSObject是Objetive-C的基类,其由NSObject类及一系列协议构成。
    其中类方法alloc、class、 description 对象方法init、dealloc、– performSelector:withObject:afterDelay:等经常被使用

    <h1>42、什么是简便构造方法?</h1> 1> 简便构造方法一般由CocoaTouch框架提供,如NSNumber的 + numberWithBool: + numberWithChar: + numberWithDouble: + numberWithFloat: + numberWithInt:
    2> Foundation下大部分类均有简便构造方法,我们可以通过简便构造方法,获得系统给我们创建好的对象,并且不需要手动释放。

    <h1>43、结构体当中能定义oc对象吗?</h1> 不能, 因为结构体当中只能是类型的声明不能进行分配空间

    <h1>44、点语法本质是什么,写一个点语法的例子,并写上注释</h1>

    点语法的本质是方法的调用,而不是访问成员变量,当使用点语法时,编译器会自动展开成相应的方法。切记点语法的本质是转换成相应的set和get方法,如果没有set和get方法,则不能使用点语法。
    例如有一个Person类 通过@property定义了name和age属性,再提供了一个run方法。
    Person *person = [Person new];
    person.name=@”itcast”;//调用了person的setName方法
    int age = person.age; // 调用了person的age方法
    person.run //调用了person的run方法
    

    <h1>45、id类型是什么,instancetype是什么,有什么区别?</h1> 1> id类型:万能指针,能作为参数,方法的返回类型。
    2> instancetype:只能作为方法的范围类型,并且返回的类型是当前定义类的类类型。

    <h1>46、成员变量名的命名以下划线开头的好处?</h1> 1> 与get方法的方法名区分开来;
    2> 可以和一些其他的局部变量区分开来,下划线开头的变量,通常都是类的成员变量。

    <h1>47、这段代码有什么问题吗:</h1>

    @implementation Person
    - (void)setAge:(int)newAge {
    self.age = newAge; }
    @end
    会死循环,会重复调用自己!self.age 改为_age即可;
    并且书写不规范:setter方法中的newAge应该为age
    

    <h1>48、截取字符串”20 | http://www.baidu.com”中,”|”字符前面和后面的数据,分别输出它们。</h1>

    NSString * str = @"20 | http://www.baidu.com";
    NSArray *array = [str componentsSeparatedByString:@"|"]; //这是分别输出的截取后的字符串
    for (int i = 0; i<[array count]; ++i) { NSLog(@"%d=%@",i,[array objectAtIndex:i]);
    }
    

    <h1>49、isKindOfClass、isMemberOfClass、selector作用分别是什么</h1> 1> isKindOfClass,作用是,某个对象属于某个类型或者继承自某类型
    2> isMemberOfClass:某个对象确切属于某个类型
    3> selector:通过方法名,获取在内存中的函数的入口地址

    <h1>50、请分别写出SEL、id、@的意思?</h1> 1> SEL是“selector”的一个类型,表示一个方法的名字-------就是一个方法的入口地址
    2> id是一个指向任何一个继承了Object(或者NSObject)类的对象。需要注意的是id是一个指针,所以在使用id 的时候不需要加*。
    3> @:OC中的指令符

    <h1>51、unsigned int 和int 有什么区别。假设int长度为65535,请写出unsigned int与 int的取值范围</h1> int:基本整型,当字节数为2时 取值范围为-32768~32767,当字节数为4时 取值范围
    负的2的31次方 到 2的31次方减1
    unsigned int:无符号基本整型,当字节数为2时 取值范围为0~65535,当字节数为4时 取值范围为0到2的32次方减1

    <h1>52、Foundation对象与Core Foundation对象有什么区别</h1> Foundation对象是OC的,Core Foundation对象是C对象
    数据类型之间的转换
    ARC:bridge_retained(持有对象所有权,F->CF)、bridge_transfer(释放对象有所权CF->F)
    非ARC: __bridge

    <h1>53、编写一个函数,实现递归删除指定路径下的所有文件。</h1>

    + (void)deleteFiles:(NSString *)path;{
        // 1.判断文件还是目录
        NSFileManager * fileManger = [NSFileManager defaultManager];
        BOOL isDir = NO;
        BOOL isExist = [fileManger fileExistsAtPath:path isDirectory:&isDir];
        if (isExist) {
            // 2. 判断是不是目录
            if (isDir) {
            NSArray * dirArray = [fileManger contentsOfDirectoryAtPath:path error:nil];
                NSString * subPath = nil;
                for (NSString * str in dirArray) {
                    subPath  = [path stringByAppendingPathComponent:str];
                    BOOL issubDir = NO;
                     [fileManger fileExistsAtPath:subPath isDirectory:&issubDir];
                    [self deleteFiles:subPath];
                }
    
    
            }else{
                NSLog(@"%@",path);
                [manager removeItemAtPath:filePath error:nil];  
            }
        }else{
            NSLog(@"你打印的是目录或者不存在");
        }
    }
    

    相关文章

      网友评论

          本文标题:iOS (2) --OC语言

          本文链接:https://www.haomeiwen.com/subject/ejwfpttx.html