随笔杂记

  • 类别

    • 是一种为现有的类添加新方法的方式
    • 利用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. }];
时间: 2024-10-12 12:33:19

随笔杂记的相关文章

【杂记随笔】查看Ubuntu系统属性

作者 作者:卢冬冬 邮箱:[email protected] 平台 系统:Ubuntu 16.04 64bit 注意 内容 1. 查看系统版本 sudo lsb_release -a 2. 查看CPU信息 cat /proc/cpuinfo 3. 查看板卡信息 cat /proc/pci 4. 查看内存信息 cat /proc/meminfo 5. 查看USB设备 cat /proc/bus/usb/devices 6. 查看键盘和鼠标 cat /proc/bus/input/devices 7

C#博客随笔之六:数据绑定

这一篇随笔记录的是在完成程序中遇到的一些情况 首先要讲的是MVVM 所谓MVVM就是Model,View,ViewModel 下面是MVVM的优点(引用自百度百科): MVVM模式和MVC模式一样,主要目的是分离视图(View)和模型(Model),有几大优点1. 低耦合.视图(View)可以独立于Model变化和修改,一个ViewModel可以绑定到不同的"View"上,当View变化的时候Model可以不变,当Model变化的时候View也可以不变.2. 可重用性.你可以把一些视图

Abby&#39;s 学习php5随笔

2017.6.27 Abby's cakephp2 学习之旅 下载了XAMPP集成开发环境,然后配置其数据库,参考学习教程, 1.建立表单. 配置完信息如下,Cache Apache默认在windows下是system用户,所以权限最高,但xampp集成环境中的apache确是administor 如何更改apache用户为system 静默开发.(一种开发方法,番茄ToDo中的学霸模式有些相似) 如何设置.ctp的显示 http://cakephp2.local/posts/index怎么就可

java基础随笔 字符数据类型char的单引号

public class Love{ public static void main(String[] args){ System.out.println('*'+'\t'+'*'); System.out.println("*"+"\t"+"*") } } 运行结果   第一行为  93 第二行为  *        * 原因 第一行中'\t' 单引号  识别为字符数据类型char,char类型是可以运算的,在第一行中+做了运算符. 第二行&q

web前端学习随笔

好好算下来,学习web前端已有半个月了,这半个月来主要学习的是HTML和CSS部分,期间有困惑,也有解决困惑时的快感,所以想把这段时间感受到的一些东西记下来,因为内容比较杂,所以干脆叫随笔吧.这里面不会说前端的相关基础知识,只是说一些自己对前端的一些认识. html是用来控制页面结构的我曾经对这句话有过疑问,觉得html应该是控制页面内容的,为什么要说是控制页面结构的呢?在查看京东首页的代码时,我恍然大悟,html确实是定义页面内容的,但同时它也要控制页面的结构.举例来说,京东商品分类的div包

JavaWeb学习随笔

Servlet学习随笔 1.HttpServlet init(ServletConfig)------Servlet生命周期中的初始方法,默认情况是服务器创建后第一次访问这个Servlet时调用,可以修改配置信息,使其在服务器一创建时就被调用; 修改配置信息的方法-----在web.xml的<servlet>下添加<load-on-startup>x<load-on-startup>,x是正整数,越小表示优先级越高 url路径的配置,完全匹配>目录匹配>(.

想知道博客园随笔总阅读量吗?

我真的是闲的无聊了...,前提是你写的随笔总数少于等于40条. 0.在选项里设置一页显示40条随笔 1,打开自己的随笔列表:https://i.cnblogs.com/posts 2,在当前页面f12打开浏览器控制台 3,粘贴进去以下代码 var trs=document.querySelectorAll('#post_list tr td:nth-child(4)')//取得阅读量 atrs=Array.from?Array.from(trs):Array.prototype.slice.ca

随笔1104

随笔1104 一.变量定义 var a = 10; 如果定义小数或整数的变量,等号后面值直接写 如果定义字符串的变量,等号后面的值要加双引号或单引号 类型转换 parseInt(); 强制转换为整数 parseFloat();强制转换为小数 二.运算符表达式 1.数学运算符 + - * / % 百分号是取余 例:alert(a+b); alert(a%b); a除以b的余数 2.逻辑运算符 && 并 指两者都满足 || 或 指两者其中任何一个满足 ! 非 指强制变反 真变假 假变真 3.比

alpha发布(技术随笔)

昨天是班级里面每个小组要进行alpha演示,大家都很努力的去做自己的项目.我们nice!组没有演示自己的项目,只一点很惭愧,身为组员没有协助组长按时完成项目,这一点自己也感觉很抱歉,虽然每天感觉自己都有去做,但是效果非常不理想.看到天天向上组的连连看界面做的很好,有背景切换,主题,游戏的级别等做的很细心.先锋组的俄罗斯方块也不错,看到同学玩的那么开心就知道了,还有飞天小女警的礼物挑选真的很用心,这个idea就很新颖,而且完成的也很好,老师也说如果转换成手机app那就更方便使用了,市场很好. 这次