• 随笔杂记


    • 类别
      • 是一种为现有的类添加新方法的方式
      • 利用Objective-C的动态运行时分配机制,可以为现有的类添加新方法

    添加的方法不可以添加新的实例变量,类别生命中没有实例变量部分

    类别的局限性有两方面局限性:

    • (1)无法向类中添加新的实例变量,类别没有位置容纳实例变量。
    • (2)名称冲突,即当类别中的方法与原始类方法名称冲突时,类别具有更高的优先级。类别方法将完全取代初始方法从而无法再使用初始方法。无法添加实例变量的局限可以使用字典对象解决

    类别主要有3个作用:(与继承的区别)

    • (1)将类的实现分散到多个不同文件或多个不同框架中。
    • (2)创建对私有方法的前向引用。
    • 三、使用类别创建前向引用
    • 如果其他类中的方法未实现,在你访问其他类的私有方法时编译器报错
    • 这时使用类别,在类别中声明这些方法(不必提供方法实现),编译器就不会再产生警告
      • (3)向对象添加非正式协议。 继承可以增加,修改或者删除方法,并且可以增加属性。

    类别只能扩充方法,而不能扩充成员变量。

    无法添加实例变量的局限可以使用字典对象解决

    runtime 机制 为类别填加实例变量。

    定义:

    @interface UIView(AddVariables)

    @property (nonatomic, retain) NSString *viewName;

    @end

    实现:

    // 定义存取的Key

    static const char *viewNameKey = "viewNameKey";

    @implementation UIView(AddVariables)

    // get方法

    - (NSString *)viewName {

        return (NSString *)objc_getAssociatedObject(self, viewNameKey);

    }

    // set方法

    - (void)setViewName:(NSString *)newViewNameKey {

        objc_setAssociatedObject(self, viewNameKey, newViewNameKey, OBJC_ASSOCIATION_RETAIN_NONATOMIC);

    }

    协议

    • 协议(protocol)类似于java语言里的接口(interface),定义了一组方法,而不提供具体实现, 只有那些“遵守”(conform to)或“采用”(adopt)了这些Protocol的类来给出自己的实现。
    • 协议不是类本身,它们仅定义了其它对象有责任实现的接口。

    跳转至tableView顶端

    [_tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] 

    atScrollPosition:UITableViewScrollPositionTop animated:YES];

    刷新当前行的图片数据

       self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];

    [self.tableView reloadata],因为会刷新整个cell,浪费性能。

    正则匹配

    NSError*error =nil;

    NSMutableAttributedString *string;

    [string addAttributes:@{NSFontAttributeName:[UIFont systemFontOfSize:12.0f]} range:NSMakeRange(0, string.length)];

    NSRegularExpression*re = [NSRegularExpression regularExpressionWithPattern:string 

    options:NSRegularExpressionCaseInsensitive error:&error];

    主线程

    (iOS UI操作必须在主线程执行)。 

    iOS异步任务一般有3种实现方式:

    • NSOperationQueue
    • GCD
    • NSThread

    关于block闭包:就是能够读取其它函数内部变量的函数

    block 配合上 dispatch_queue,可以方便地实现简单的多线程编程和异步编程(GCD)

    (1)遍历数组或者字典

    (2)视图动画

    (3)排序

    (4)通知

    (5)错误处理

    (6)多线程

    (7)封装变化点

    block的实现是基于指针和函数指针。

    注意点:

    1.在使用block前需要对block指针做判空处理。不判空直接使用,一旦指针为空直接产生崩溃

    2.将block赋值为空,是解掉循环引用的重要方法。

    3.使用方将self或成员变量加入block之前要先将self变为__weak

    4.在多线程环境下(block中的weakSelf有可能被析构的情况下),需要先将self转为strong指针,避免在运行到某个关键步骤时self对象被析 构。

    Runloop

    3、Runloop内部逻辑:关键在两个判断点(是否睡觉,是否退出)

             - 代码实现:

             - 函数作用栈显示:

    4、Runloop本质:mach port和mach_msg()。

    5、如何处理事件:

             - 界面刷新:

             - 手势识别:

             - GCD任务:

             - timer:(与CADisplayLink)

             - 网络请求:

    6、应用:

             - 滑动与图片刷新;

             - 常驻子线程,保持子线程一直处理事件

    Runloop的寄生于线程:

    一个线程只能有唯一对应的runloop;但这个根runloop里可以嵌套子runloops;

    自动释放池寄生于Runloop:

    程序启动后,主线程注册了两个Observer监听runloop的进出与睡觉。

    一个最高优先级OB监测Entry状态;

    一个最低优先级OB监听BeforeWaiting状态和Exit状态。

    线程(创建)-->runloop将进入-->最高优先级OB创建释放池-->runloop将睡-->最低优先级OB销毁旧池创建新池-->runloop将退出-->最低优先级OB销毁新池-->线程(销毁)

    Runloop有两个关键判断点,一个是通过msg决定Runloop是否等待,一个是通过判断退出条件来决定Runloop是否循环

    网络请求:

    关于网络请求的接口:

    最底层是CFSocket层,

    然后是CFNetwork将其封装,

    然后是NSURLConnection对CFNetwork进行面向对象的封装

    SQL语言共分为四大类:数据查询语言DQL,数据操纵语言DML,数据定义语言DDL,数据控制语言DCL。

    SQLLite

    . 弱类型:数据存储类型可以不同(主键除外)

    SQLite采用的是动态数据类型

    SQLite中采用了Page Cache的缓冲优化机制

    优化策略: 1. 编译时参数SQLITE_TEMP_STORE:

    2. 运行时指令temp_store pragma:

    3. 临时文件的大小:

    4.SQLITE_DEFAULT_TEMP_CACHE_SIZE编译期参数可以用于指定临时表和索引

    在占用多少 Cache Page时才需要被刷新到磁盘文件,该参数的缺省值为500页。

    ACID(Atomic, Consistent, Isolated, and Durable)原子性,一致性,独立性,持久性

    1.在SQLite中,锁和并发控制机制都是由pager_module模块负责处理

    2.它不关心数据的存储结构,如B-tree ,编码格式,索引,默认统一大小为一页(page),1024字节

    文件锁:

    1). UNLOCKED:(无锁)缺省状态。

    2). SHARED:(共享锁)只能读操作(并发的),不能写操作

    3). RESERVED: (保留锁)一个进程将来的某个时间会执行写操作,同一时间只能存在一个保留锁(写)和多个共享锁(读)

    (即如果存在了一个保留锁,则其他的写操作就被屏蔽啦,其他写操作失败)

    4). PENDING: (等待锁)此时所有的读操作都不被允许(禁止新的读取),等待现有的共享锁全部消失,进行写操作(俗称挂起状态)

    5). EXCLUSIVE:(排他锁)为了最大化并发效率,SQLite将会最小化排他锁被持有的时间总量。

    某一进程要想在数据库上执行写操作,

    那么必须先获取共享锁,

    在共享锁获取之后再获取 保留锁,  -----------------------------    同一时刻只有一 个进程可以持有一把保留锁

    当准备写的时候如果还有共享锁存在,就换成等待锁————————没有共享锁就直接获取排他锁

    写操作的时候必须获取该数据库的排他锁

    1、成功获取保留锁之后,该写进程将创建回滚日志

    2、进行完写操作之后,一定要删除日志文件和从所有数据库中删除掉排他锁和PENDING锁,解除对文件的控制。

    先将sql语句编译成字节码,之后交给自带的虚拟机去执行(无需解析成复杂的数据结构)

    核心接口

    sqlite3_open    返回的 database_connection对象

    sqlite3_prepare   将SQL文本转换为prepared_statement对象 ,返回该对象的指针,初始化为待 执行的状态

    sqlite3_step    评估prepared_statement对象 prepared_statement对象的内部指针将指向其返回的结果集的第一行

    sqlite3_column  由一组相关的接口函数来完成该功能,其中每个函数都返回不同 类型的数据

    sqlite3_finalize 用于销毁prepared statement对象,防止内存泄露

    sqlite3_close 关闭之前打开的database_connection对象,之前必须销毁所有与其有关的prepared_statements

    通过SQLite自带 的ATTACH命令可以在一个连接中方便的访问多个数据库

    参数绑定 

    涉及的API接口:sqlite3_reset和sqlite3_bind。

    1.占位符的使用

    2.sqlite3_prepare_v2的执行效率往往要低于 sqlite3_step

    3.

    不带参数绑定的情况下

    strSQL=(“insert into testtable values(%d)",i);

     sqlite3_prepare_v2(strSQL); 

    sqlite3_step(prepared_statement); 

    sqlite3_finalize(prepared_stmt);

    2. 参数绑定的情况下插入多条数据。

    string strSQLWithParameter = "insert into testtable values(?)"; 

    sqlite3_prepare_v2(..., strSQL);
 for (int i = 0; i < MAX_ROWS; ++i) {

    sqlite3_bind(...,i);

     sqlite3_step(prepared_stmt); 

    sqlite3_reset(prepared_stmt);

    }

    总结:

    使用动态绑定,可以节省大量的sqlite3_prepare_v2函数调用次数,从而节省了多次将同一SQL语句编译成SQLite内部识别的字节码所用的时间

    SQL 语句

    1. schema

    sqlite> .schema testtable2
 CREATE TABLE testtable2(first_col INT);

    .schema命令是sqlite3命令行工具的内置命令,用于显示当前数据表的CREATE TABLE语 句。

     .header on --查询结果将字段名作为标题输出。

    2. 在指定数据库创建表:

    sqlite> ATTACH DATABASE 'd:/mydb.db' AS mydb;

      sqlite> CREATE TABLE mydb.testtable (first_col integer); 需要指定,默认会在当前连接的main数据库中创建

    Detach  卸载数据库

    3."IF NOT EXISTS"从句:

    sqlite> CREATE TABLE IF NOT EXISTS testtable (first_col integer);

    4. CREATE TABLE ... AS SELECT:

    . 在SQLite中,NULL值被视为和其他任何值都是不同的 

    sqlite> CREATE TABLE testtable2 AS SELECT * FROM testtable;

    5. 主键约束

    sqlite> CREATE TABLE testtable2 (

    ＀  first_col integer, 

    ＀  second_col integer, 

    ＀   PRIMARY KEY (first_col,second_col) >

    ＀   ); 

    . 6. 唯一性约束: 
--直接在字段的定义上指定唯一性约束。 
sqlite> CREATE TABLE testtable (first_col integer UNIQUE); 

    . 7. 为空(NOT NULL)约束: 

    . 8. 检查性约束: 
sqlite> CREATE TABLE testtable (first_col integer CHECK (first_col < 5));


    . 转换表达式:

    .  CAST(expr AS target_type)

    比较运算中

    如果其中一个操 作数为NULL,那么它们的结果亦为NULL

    . 1. 修改表名: 

    .  sqlite> ALTER TABLE testtable RENAME TO testtable2; 

    . 2. 新增字段: 

    sqlite> ALTER TABLE testtable ADD COLUMN second_col integer; 

    . 表的删除: 

    . DROP TABLE IF EXISTS testtable; 

    聚合函数

    返回一个把所有查询结果用逗号连接的字符串

    SELECT group_concat(app.appName ,  ', ') FROM app

    内置函数

    返回移除包含天的字符串

    SELECT ltrim(app.appName,'天') from app

    --返回当前年中10月份的第一个星期二是日期。
  SELECT date('now','start of year','+9 months','weekday 2');

    索引和数据分析

    --创建唯一性索引,该索引规则和数据表的唯一性约束的规则相同,即NULL和任何值都不 同,包括NULL本身。

    CREATE UNIQUE INDEX table_idx ON table(second_col DESC);

    .indices命令的输出可以看出当前表的所有索引

    数据分析

    和PostgreSQL非常相似,SQLite中的ANALYZE命令也同样用于分析数据表和索引中的数 据,并将统计结果存放于SQLite的内部系统表中,以便于查询优化器可以根据分析后的统计 数据选择最优的查询执行路径,从而提高整个查询的效率

    数据清理:

    在SQLite中,仅支持清理当前连接中的主数据库,而不能清理其它Attached数据库。

    sqlite> VACUUM;

    SQLite中主要产生以下七种临时文件,如:

    1). 回滚日志。
2). 主数据库日志。
3). SQL语句日志。
4). 临时数据库文件。
5). 视图和子查询的临时持久化文件。
6). 临时索引文件。
7). VACUUM命令使用的临时数据库文件。

    数据库和事物

    如果一个事务包含多个Attached数据库操作,那么该事务仍然是原子的

    线程

    注意回到主线程,有些回调并不在主线程中,所以这里必须回到主线程

       dispatch_async(dispatch_get_main_queue(), ^{

            

           [self showMsg:str];

      });

    1. /**始终记住, 通过模型来修改显示. 而不要试图直接修改显示*/  

    异步获取图片,主线程刷新图片 ( 使用SDWebImage来完成这个功能. 针对ImageView.就是一句话  )

    1. [self.queue addOperationWithBlock: ^{  
    2. NSData *imgData = [NSData dataWithContentsOfURL:[NSURL URLWithString:app.icon]]; //得到图像数据  
    3. UIImage *image = [UIImage imageWithData:imgData];  
    4. //在主线程中更新UI  
    5. [[NSOperationQueue mainQueue] addOperationWithBlock: ^{  
    6. //通过修改模型, 来修改数据  
    7. app.image = image;  
    8. //刷新指定表格行  
    9. [self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];  
    10. }];  
    11. }];  
  • 相关阅读:
    js弹出DIV层
    .net 生成静态页面
    新开博客
    随机生成验证码
    ASP.NET错误处理方法总结
    webgis
    看樱花
    今天转载的笑话,挺好笑呵
    用Tomcat插件在Eclipse上搭建可跟踪调试的J2EE WEB开发环境
    关于JSTL的简单说明
  • 原文地址:https://www.cnblogs.com/guaishushu/p/4979112.html
Copyright © 2020-2023  润新知