• 【iOS】重读《精通Objective-C》(一)


    转载请注明出处!!!

    由于比较空闲,近期打算把之前看过的书一本本重读一下。这一小节主要说的是《精通Objective-C》的前六章。

    1.为什么选择objective-c

    面向对象的编程语言,对象消息传递,动态的运行时环境,内存管理,内部检查和获取消息,对C语言的支持,苹果公司的技术。

    2.OOP:面向对象设计

    面向对象编程是一种计算机程序设计方式,其重点是创建和使用软件对象编写程序。软件对象提供了被建模事物/概念的特点或属性的一种表现形式,以及他们可以做的事情。

    3.设置访问实例变量的方式

    @private:只能在声明他的类以及该类型相同的其他实例中访问

    @protexted:只能在声明他的类及其子类的实例方法中访问

    @public:可被任意代码访问

    @package:可被其他类实例和函数访问,但在其所属的程序包外部被视为私有变量

    4.属性和实例变量(不太清楚,具体在查一查)

    属性可在累的外部调用,可以看做是在.h文件中声明的

    实例变量一般是在.m中声明的,外部不可以调用访问

    5.属性的特性

    nonatomic  非原子性  可以在多线程并发的情况下,将访问器设置为非原子性的,因而可以提供不同的结果

    atomic       原子性    

    assign       可以在不使用copy和retain的情况下,使属性的设置器方法执行简单的赋值操作  默认设置

    retain        在赋值时,输入值会发送一条保留消息,而上一个值会被发送一条释放消息

    copy         在赋值时,输入值会发送一条新消息的副本,而上一个值会被发送一条释放消息

    strong       ARC内存管理下相当于retain

    weak         ARC内存管理下与assign类似,但如果引用对象被释放了,属性的值为nil

    readwrite   可读可写  必须实现getter和setter方法  默认

    readonly     只读   必需实现getter

    getter==getterName    getter方法重命名

    setter== setterName    setter方法重命名

    6.nonatomic和atomic两者区别:

    Atomic  是默认的 会保证CPU能在背的线程访问这个属性之前 先执行当前流程  速度不快

    nonatomic  非默认  更快 线程不安全  如果有两个线程访问同一个属性,会出现无法预料的结果

    参考链接:https://www.jianshu.com/p/7288eacbb1a2

    设有一个 atomic 的属性 "name",如果线程 A 调[self setName:@"A"],线程 B 调[self setName:@"B"],线程 C 调[self name],那么所有这些不同线程上的操作都将依次顺序执行——也就是说,如果一个线程正在执行 getter/setter,其他线程就得等待。因此,属性 name 是读/写安全的。

    但是,如果有另一个线程 D 同时在调[name release],那可能就会crash,因为 release 不受 getter/setter 操作的限制。也就是说,这个属性只能说是读/写安全的,但并不是线程安全的,因为别的线程还能进行读写之外的其他操作。线程安全需要开发者自己来保证。

    如果 name 属性是 nonatomic 的,那么上面例子里的所有线程 A、B、C、D 都可以同时执行,可能导致无法预料的结果。如果是 atomic 的,那么 A、B、C 会串行,而 D 还是并行的。

    7.assign、copy、retain三者区别

    Assign: 简单赋值,不改变索引计数

    Copy:建立一个索引计数为1的对象,然后释放旧对象

    Retain:释放旧的对象,将对象的值赋予输入对象,在提高输入对象的索引计数

    参考链接:https://www.jianshu.com/p/158c979f9b30

    8.协议

    协议的声明以@protocol开头,后跟协议的名称,以@end结束。协议有必选方法和可选方法(以@required和@optional区分,不写默认必选方法)

    9.objective-c提供了两类消息转发选项

    快速转发:NSObject的子类可以通过重写NSObject类的forwardingTargetForSelector:方法,将该方法转发给其他对象,从而实现快速转发。

    标准转发:NSObject的子类可以通过重写NSObject类的forwardingInvocation:方法,实现标准转发。

    10.内存泄露——程序没有释放不再使用的对象

        悬挂指针——程序释放了仍在使用的对象

    11.ARC的生命周期限定符

    __strong:表明任何使用alloc/init消息创建的对象都会在其作用范围内保留

    __weak:表明对象随时可以被释放。只有当对象拥有其他强引用是该标记才有用。释放后,带__weak限定符的变量会被设置为nil

    __unsafe_unretained:与__weak类似,但在对象释放后不会设置为nil,处于悬挂状态

    __autoreleasing:用于通过引用传递对象

    12.避免循环引用

    Objective-C的引用计数模型是通过获取对象的所有权(retain消息),以及在不在使用对象后释放对象的所有权(release消息)实现的。ARC自动化了该过程。但是如果两个对象直接或间接相互引用,就会导致循环引用问题。

    13.预处理器

    Objective-C编译器编译源代码的一般流程是:接受源文件,然后把它们转换为能够在目标平台上执行的文件。

    预处理器是在语法分析阶段前的语法分析阶段发挥作用的。

    预处理语言

    预处理语言是一门不同于Objective-C的独立编程语言。预处理语言对原文件进行的转换主要包括源文件的内容、条件编译和宏展开。预处理器语言元素会在程序边以前处理源文件,但预处理器不能识别Objective-C代码。

    预处理器指令是指由预处理器执行的命令

    宏指令是指具有名称的一段代码。当该名称在源代码中使用,就会被替换为它代表的那段代码。

    指令

    Objective-C源文件中的预处理器指令会使用独特的语法,是他们由预处理器(而不是编译器)处理。

    预处理器指令形式: #指令名 指令参数

    预处理器指令会将换行符号用作结束符号。要使预处理器扩展为多行,可使用反斜杠()连接多行代码

    成套的预处理器指令及其作用

    头文件包含(#include、#import)

    作用是是预处理器获得被包含文件的文本,并将其插入到当前文件中。

    #import和#Include的区别

    #import指令可以确保头文件仅在源文件中被包含一次,防止递归包含。

    条件编译(#if、#elif、#else、#endif、#ifdef和#ifndef)

    #if指令可以测试表达式的值,并根据结果确定是否包含部分源文件 与#endif指令配对使用

    诊断(#error、#warning和#line)

    #pragma指令

    宏是指有名称的代码段。使用#define 定义宏使用#undef移除宏

    关于预处理器的部分还可以看我的上一篇博客。 

  • 相关阅读:
    Struct2_使用Ajax调用Action方法并返回值
    Eclipse使用maven创建struct2项目及遇到的各种坑
    IIS7.5 提示未在本地计算机上注册“Microsoft.Jet.OleDb.4.0”提供程序
    使用Canvas实现下雪功能
    基于脚本的动画的计时控制(“requestAnimationFrame”)(转)
    pointer-events属性
    chrome Provisional headers are shown错误提示
    Wcf资料收集
    Asp.Net WebApi 启用CORS跨域访问指定多个域名
    Cors 跨域Access-Control-Allow-Origin
  • 原文地址:https://www.cnblogs.com/weicyNo-1/p/8529340.html
Copyright © 2020-2023  润新知