iOS 核心面试题

@property 后面可以有哪些修饰符?

1.读写性修饰符:readwrite | readonly

readwrite:表明这个属性是可读可写的,系统为我们创建这个属性的setter和getter方法。

readonly:表明这个属性只能读不能写,系统只为我们创建一个getter方法,不会创建setter方法

2.setter相关修饰符:assign | retain | copy

setter相关的修饰符表明setter方法应该如何实现

assign:表示直接赋值,用于基本数据类型(NSInteger和CGFloat)和C数据类型(如int, float, double, char等)另外还有id类型,这个修饰符不会牵涉到内存管理。但是如果是对象类型,使用此修饰符则可能会导致内存泄漏或EXC_BAD_ACCESS错误

retain:针对对象类型进行内存管理。如果对基本数据类型使用,则Xcode会直接报错。当给对象类型使用此修饰符时,setter方法会先将旧的对象属性release掉,再对新的对象进行一次赋值并进行一次retain操作

copy:主要用在NSString类型,表示复制内容。

系统默认属性是assign。retain是指针的复制,copy是内容的复制

3.原子性修饰符:atomic | nonatomic

atomic:表示是线程安全的。

nonatomic:表示是非线程安全的,使用此属性性能会提高一些。

系统默认是atomic

4.getter和setter修饰符

@property(getter = getMethodName, setter = setMethodName) Object *obj;

这两个属性修饰符用于设置自定义生成的getter和setter方法名,使用之后将不再使用系统默认的setter和getter方法名。

在@property修饰符中可以出现多个修饰符,分别用逗号分隔,但是,在上述修饰符中,1,2,3组中的属性分别之恩那个出现一个,只有4中可以同时出现。

Xcode4.2(iOS sdk4.3和以下版本)和以前的版本用retain和assign

Xcode4.3(iOS 5和以上版本)或之后有了ARC用strong和weak

assign:用于非指针变量。用于基础数据类型(如NSInteger, CGFloat)和C数据类型(int, float, double, char等), 另外还有id类型。

记住:前面不需要加*的就用assign

retain:用于指针变量。一般用于字符串(NSString, NSMutableString), 数组(NSMutableArray, NSArray),字典对象,视图对象(UIView),控制器对象(UIViewController)等

strong类似于retain,weak类似于assign

最简单的记忆:

使用assign:对基础数据类型(如NSInteger, CGFloat)和C数据类型(int, float, double, char等), 另外还有id类型

使用copy:对NSString类型

使用retain:对其它NSObject和其子类

1、在头文件中用@property声明一个属性名,编译器会自动为我们转换成这个属性名的getter方法和setter方法。

2、在实现文件中使用@synthesize propertyName,编译器先会查找这个属性名的setter方法和getter方法有没有被人为实现,如果已经实现,则不再实现,如果没有,则会帮我们生成一个属性命的setter方法和getter方法。

3、当在实现文件中使用了@synthesize propertyName,编译器还会做一件事情,在类成员变量中查找一个名为_propertyName的成员变量,如果没有,再继续查找名为propertyName的成员变量,如果这两个都没有,编译器会自动为我们生成一个私有的名为_propertyName的成员变量。注意,系统自动创建的都是私有的。

4、当在实现文件中这样写@synthesize propertyName = varName;时,setter和getter方法所对应的是一个名为varName的成员变量,修改和读取的是varName成员变量的值。

5、当我们在实现文件中不写@synthesize propertyName时,在Xcode 4.5之前的版本不会帮我们自动实现setter和getter方法,系统当然也不再会为我们生成对应的成员变量。但是在Xcode 4.5之后可以不用写@synthesize了,就跟3、4一样了。

6、当我们既定义了@synthesize,又在实现文件中人为重写setter和getter方法时,那么@synthesize将不再工作,也就不会为我们创建没有定义的_propertyName成员变量了,这时候如果在setter和getter方法中调用_propertyName将会发生编译错误!



用@property声明的NSString(或NSArray,NSDictionary)经常使用copy关键字,为什么?如果改用strong关键字,可能造成什么问题?

  使用 copy 的目的是为了让本对象的属性不受外界影响,使用copy无论给我传入是一个可变对象还是不可对象,我本身持有的就是一个不可变的副本.

如果使用 strong .这个属性有可能指向一个可变对象,如果这个可变对象被外部意外的修改了,由于可变对象被改变之后起始地址不会发生变化。而附有strong修饰的属性依然指向这这块内存地址,下次读取的时候就会是被改变以后的对象了.也就是说如果使用 strong 可能会被外部意外的修改。

    @property (nonatomic, copy)   NSString *str_copy;
    @property (nonatomic, strong) NSString *str_strong;
    @property (nonatomic, assign) NSString *str_assign;
    
    
    //可变对象
    NSMutableString *string = [NSMutableString stringWithString:@"hello"];
    
    self.str_copy = string;
    self.str_strong = string;
    self.str_assign = string;
    [string appendString:@"word!"];
    
    //string 改变后,self.str_copy 值不变,self.str_strong,self.str_assign 都跟着变



@protocol 和 category 中如何使用 @property?

          在protocol中使用property只会生成setter和getter方法声明,我们使用属性的目的,是希望遵守我协议的对象的实现该属性

          category 使用 @property 也是只会生成setter和getter方法的声明,如果我们真的需要给category增加属性的实现,需要借助于运行Objective-C动态运行机制中的两个函数

                   objc_setAssociatedObject

                   objc_getAssociatedObject


@synthesize和@dynamic分别有什么作用?

          @property有两个对应的词,一个是@synthesize,一个是@dynamic。如果@synthesize和@dynamic都没写,那么默认的就是@syntheszie var = var,var为property变量。可以手动修改属性var对应的实例变量。例如:@syntheszie var = var1

          @synthesize的语义是如果你没有手动实现setter方法和getter方法,那么编译器会自动为你加上这两个方法, 在Xcode4.4之后的版本可以省略不写.

          @dynamic告诉编译器不要自动生成成员变量的getter和setter方法,而是开发者自己手工生成或者运行时生成.


一个objc对象的isa的指针指向什么?有什么作用?

objc对象的isa指针指向类对象,用于寻找对象的方法。



objc中的类方法和实例方法有什么本质区别和联系?

类方法

          类方法保存在类对象的元类中

          类方法只能通过类对象调用

          类方法中的self是类对象

          类方法中不能访问成员变量

          类方法中不能直接调用对象方法

实例方法

          保存在类对象的对象模型中

          实例方法只能通过实例对象调用

          实例方法中的self是实例对象

          实例方法中可以访问成员变量

          实例方法中可以访问成员变量

          实例方法中可以访问成员变量



以+ scheduledTimerWithTimeInterval…的方式触发的timer,在滑动页面上的列表时,timer会暂定回调,为什么?如何解决?

          当前主线程的 RunLoop 正在以 UITrackingRunLoopMode 的模式运行。 这个时候 RunLoop 只会处理与 UITrackingRunLoopMode “绑定”的源, 比如触摸、滚动等事件;而 NSTimer 是默认“绑定”到 NSRunLoopDefaultMode 上的, 所以 Timer 是事情是不会被 RunLoop 处理的,定时器被暂停了!

          常见的解决方案是把Timer“绑定”到 NSRunLoopCommonModes 模式上:

[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];

这样这个Timer就可以和当前组中的两种模式 UITrackingRunLoopMode 和 kCFRunLoopDefaultMode 相关联了。 RunLoop在这两种模式下,Timer都可以正常运行了。



BAD_ACCESS在什么情况下出现?

          对一个已经释放的对象执行了release

          执行了死循环


苹果是如何实现autoreleasepool的?

autoreleasepool以一个队列数组的形式实现,主要通过下列三个函数完成.

          objc_autoreleasepoolPush

          objc_autoreleasepoolPop

          objc_aurorelease

函数名就可以知道,对autorelease分别执行push,和pop操作。销毁对象时执行release操作。



如何用GCD同步若干个异步调用?(如何让多个线程同时执行同一块代码?)(如根据若干个url异步加载多张图片,然后在都下载完成后合成一张整图)

使用Dispatch Group追加block到Global Group Queue,这些block如果全部执行完毕,就会执行Main Dispatch Queue中的结束处理的block。

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

dispatch_group_t group = dispatch_group_create();

dispatch_group_async(group, queue, ^{ /*加载图片1 */ });

dispatch_group_async(group, queue, ^{ /*加载图片2 */ });

dispatch_group_async(group, queue, ^{ /*加载图片3 */ });

dispatch_group_notify(group, dispatch_get_main_queue(), ^{

        // 合并图片

});


dispatch_barrier_async的作用是什么?

dispatch_barrier_async函数会等待追加到Concurrent Dispatch Queue并行队列中的操作全部执行完之后,然后再执行dispatch_barrier_async函数追加的处理,等dispatch_barrier_async追加的处理执行结束之后,Concurrent Dispatch Queue才恢复之前的动作继续执行。

打个比方:比如你在看电视每个台都在播放精彩的内容,突然插进来一则广告。于是你就换台,结果发现每个台都在放这个广告,等这个广告播放完之后,各个台才开始恢复原来播放的内容。dispatch_barrier_async函数追加的内容就如这条广告。


什么是method swizzling?

在Objective-C中调用一个方法,其实是向一个对象发送消息,查找消息的唯一依据是selector的名字。利用Objective-C的动态特性,可以实现在运行时偷换selector对应的方法实现,达到给方法挂钩的目的。

每个类都有一个方法列表,存放着selector的名字和方法实现的映射关系。IMP有点类似函数指针,指向具体的Method实现。


为什么其他语言里叫函数调用,Object-C里则叫给我对象发消息(或者谈下对runtime的理解)

java中,类和方法在编译期就绑定在一起

在OC中,方法调用是向类发送消息,如(bady cry)在运行时会转换成objc_msgSend(bady,cry),向对象发送消息时根据isa指针找到类,在根据类的调度表查找方法,没找到方法则在父类中查找直至基类,如果始终没有找到返回nil

Objective-C 的 Runtime 铸就了它动态语言的特性,这些深层次的知识虽然平时写代码用的少一些,但是却是每个 Objc 程序员需要了解的。Objc Runtime使得C具有了面向对象能力,在程序运行时创建,检查,修改类、对象和它们的方法。可以使用runtime的一系列方法实现。


TCP和UDP有什么区别?

TCP是面向连接的,建立连接需要经历三次握手,保证数据正确性和数据顺序

UDP是非连接的协议,传送数据受生成速度,传输带宽等限制,可能造成丢包

UDP一台服务端可以同时向多个客户端传输信息

TCP报头体积更大,对系统资源要求更多


+(void)load; +(void)initialize;有什么用处?

当类对象被引入项目时, runtime 会向每一个类对象发送 load 消息. load 方法还是非常的神奇的, 因为它会在每一个类甚至分类被引入时仅调用一次, 调用的顺序是父类优先于子类, 子类优先于分类. 而且 load 方法不会被类自动继承, 每一个类中的 load 方法都不需要像 viewDidLoad 方法一样调用父类的方法. 由于 load 方法会在类被 import 时调用一次, 而这时往往是改变类的行为的最佳时机. 我在 DKNightVersion 中使用 method swizlling 来修改原有的方法时, 就是在分类 load 中实现的.

initialize 方法和 load 方法有一些不同, 它虽然也会在整个 runtime 过程中调用一次, 但是它是在该类的第一个方法执行之前调用, 也就是说 initialize 的调用是惰性的, 它的实现也与我们在平时使用的惰性初始化属性时基本相同. 我在实际的项目中并没有遇到过必须使用这个方法的情况, 在该方法中主要做静态变量的设置并用于确保在实例初始化前某些条件必须满足.

在Objective-C中,runtime会自动调用每个类的两个方法。+load会在类初始加载时调用,+initialize会在第一次调用类的类方法或实例方法之前被调用。这两个方法是可选的,且只有在实现了它们时才会被调用。

共同点:两个方法都只会被调用一次。



使用drawRect有什么影响?(这个可深可浅,你至少得用过。。)

drawRect方法依赖Core Graphics框架来进行自定义的绘制,但这种方法主要的缺点就是它处理touch事件的方式:每次按钮被点击后,都会用setNeddsDisplay进行强制重绘;而且不止一次,每次单点事件触发两次执行。这样的话从性能的角度来说,对CPU和内存来说都是欠佳的。特别是如果在我们的界面上有多个这样的UIButton实例。

这个方法的主要作用是根据传入的 rect 来绘制图像 参见文档. 这个方法的默认实现没有做任何事情, 我们可以在这个方法中使用 Core Graphics 和 UIKit 来绘制视图的内容.

这个方法的调用机制也是非常特别. 当你调用 setNeedsDisplay 方法时, UIKit 将会把当前图层标记为 dirty, 但还是会显示原来的内容, 直到下一次的视图渲染周期, 才会为标记为 dirty 的图层重新建立 Core Graphics 上下文, 然后将内存中的数据恢复出来, 再使用 CGContextRef 进行绘制.


sip是什么?

1> SIP(Session Initiation Protocol),会话发起协议

2> SIP是建立VOIP连接的 IETF 标准,IETF是全球互联网最具权威的技术标准化组织

3> 所谓VOIP,就是网络电话,直接用互联网打电话,不用耗手机话费



在异步线程中下载很多图片,如果失败了,该如何处理?请结合RunLoop来谈谈解决方案.(提示:在异步线程中启动一个RunLoop重新发送网络请求,下载图片)

1> 重新下载图片

2> 下载完毕, 利用RunLoop的输入源回到主线程刷新UIImageVIUew



如果后期需要增加数据库中的字段怎么实现,如果不使用CoreData呢?

编写SQL语句来操作原来表中的字段

1> 增加表字段

ALTER TABLE 表名 ADD COLUMN 字段名 字段类型;

2> 删除表字段

ALTER TABLE 表名 DROP COLUMN 字段名;

3> 修改表字段

ALTER TABLE 表名 RENAME COLUMN 旧字段名 TO 新字段名;



简单描述下客户端的缓存机制?

1. 缓存可以分为:内存数据缓存、数据库缓存、文件缓存

2. 每次想获取数据的时候

1> 先检测内存中有无缓存

2> 再检测本地有无缓存(数据库/文件)

3> 最终发送网络请求

4> 将服务器返回的网络数据进行缓存(内存、数据库、文件), 以便下次读取


利用Socket建立网络连接的步骤

建立Socket连接至少需要一对套接字,其中一个运行于客户端,称为ClientSocket ,另一个运行于服务器端,称为ServerSocket 。

套接字之间的连接过程分为三个步骤:服务器监听,客户端请求,连接确认。

1。服务器监听:服务器端套接字并不定位具体的客户端套接字,而是处于等待连接的状态,实时监控网络状态,等待客户端的连接请求。

2。客户端请求:指客户端的套接字提出连接请求,要连接的目标是服务器端的套接字。为此,客户端的套接字必须首先描述它要连接的服务器的套接字,指出服务器端套接字的地址和端口号,然后就向服务器端套接字提出连接请求。

3。连接确认:当服务器端套接字监听到或者说接收到客户端套接字的连接请求时,就响应客户端套接字的请求,建立一个新的线程,把服务器端套接字的描述发给客户端,一旦客户端确认了此描述,双方就正式建立连接。而服务器端套接字继续处于监听状态,继续接收其他客户端套接字的连接请求








【6层】一字型框架办公楼(含建筑结构图、计算书) 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
深度学习是机器学习的一个子领域,它基于人工神经网络的研究,特别是利用多层次的神经网络来进行学习和模式识别。深度学习模型能够学习数据的高层次特征,这些特征对于图像和语音识别、自然语言处理、医学图像分析等应用至关重要。以下是深度学习的一些关键概念和组成部分: 1. **神经网络(Neural Networks)**:深度学习的基础是人工神经网络,它是由多个层组成的网络结构,包括输入层、隐藏层和输出层。每个层由多个神经元组成,神经元之间通过权重连接。 2. **前馈神经网络(Feedforward Neural Networks)**:这是最常见的神经网络类型,信息从输入层流向隐藏层,最终到达输出层。 3. **卷积神经网络(Convolutional Neural Networks, CNNs)**:这种网络特别适合处理具有网格结构的数据,如图像。它们使用卷积层来提取图像的特征。 4. **循环神经网络(Recurrent Neural Networks, RNNs)**:这种网络能够处理序列数据,如时间序列或自然语言,因为它们具有记忆功能,能够捕捉数据中的时间依赖性。 5. **长短期记忆网络(Long Short-Term Memory, LSTM)**:LSTM 是一种特殊的 RNN,它能够学习长期依赖关系,非常适合复杂的序列预测任务。 6. **生成对抗网络(Generative Adversarial Networks, GANs)**:由两个网络组成,一个生成器和一个判别器,它们相互竞争,生成器生成数据,判别器评估数据的真实性。 7. **深度学习框架**:如 TensorFlow、Keras、PyTorch 等,这些框架提供了构建、训练和部署深度学习模型的工具和库。 8. **激活函数(Activation Functions)**:如 ReLU、Sigmoid、Tanh 等,它们在神经网络中用于添加非线性,使得网络能够学习复杂的函数。 9. **损失函数(Loss Functions)**:用于评估模型的预测与真实值之间的差异,常见的损失函数包括均方误差(MSE)、交叉熵(Cross-Entropy)等。 10. **优化算法(Optimization Algorithms)**:如梯度下降(Gradient Descent)、随机梯度下降(SGD)、Adam 等,用于更新网络权重,以最小化损失函数。 11. **正则化(Regularization)**:技术如 Dropout、L1/L2 正则化等,用于防止模型过拟合。 12. **迁移学习(Transfer Learning)**:利用在一个任务上训练好的模型来提高另一个相关任务的性能。 深度学习在许多领域都取得了显著的成就,但它也面临着一些挑战,如对大量数据的依赖、模型的解释性差、计算资源消耗大等。研究人员正在不断探索新的方法来解决这些问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值