任成の博客

朝闻道,夕可眠矣

一个灵活又方便的网页解析库,处理高效,支持多种解析器。
利用它就不用编写正则表达式也能方便的实现网页信息的抓取

阅读全文 »

XPath即为XML路径语言(XML Path Language);
在XML文档中查找信息的语言,同样适用于HTML文档的检索;
lxml库的使用

阅读全文 »

urllib在Python2.x中内置的库是urllib和urllib2,在Python3.x中合并为urllib库。
urllib是系统内置库,提供了一系列用于操作URL的功能。

阅读全文 »

Python内置的urllib模块,用于访问网络资源。但是,它用起来比较麻烦,而且,缺少很多实用的高级功能。
它是一个Python第三方库,处理URL资源特别方便。

阅读全文 »

网络爬虫(又被称为网页蜘蛛,网络机器人,在FOAF社区中间,更经常的称为网页追逐者),是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本。另外一些不常使用的名字还有蚂蚁、自动索引、模拟程序或者蠕虫。

阅读全文 »

常用概念

内存泄露

该释放的对象没有释放

iOS程序的内存布局

  • 代码段:编译之后的代码
  • 数据段
    • 字符串常量:比如NSString *str = @”123”
    • 已初始化数据:已初始化的全局变量、静态变量等
    • 未初始化数据:未初始化的全局变量、静态变量等
  • 栈:函数调用开销,比如局部变量。分配的内存空间地址越来越小
  • 堆:通过alloc、malloc、calloc等动态分配的空间,分配的内存空间地址越来越大

Tagged Pointer

从64bit开始,iOS引入了Tagged Pointer技术,用于优化NSNumberNSDateNSString等小对象的存储

在没有使用Tagged Pointer之前, NSNumber等对象需要动态分配内存、维护引用计数等,NSNumber指针存储的是堆中NSNumber`对象的地址值

使用Tagged Pointer之后,NSNumber指针里面存储的数据变成了:Tag + Data,也就是将数据直接存储在了指针中。当指针不够存储数据时,才会使用动态分配内存的方式来存储数据

objc_msgSend能识别Tagged Pointer,比如NSNumberintValue方法,直接从指针提取数据,节省了以前的调用开销

如何判断一个指针是否为Tagged Pointer?
iOS平台,最高有效位是1(第64bit);WWDC2020:最低有效位是1
Mac平台,最低有效位是1

OC对象的内存管理

在iOS中,使用引用计数来管理OC对象的内存.

  • 一个新创建的OC对象引用计数默认是1,当引用计数减为0,OC对象就会销毁,释放其占用的内存空间

  • 调用retain会让OC对象的引用计数+1,调用release会让OC对象的引用计数-1

  • 拥有某个对象,就让它的引用计数+1想再拥有某个对象,就让它的引用计数-1

@property
旧:生成一个成员变量,以及setter和getter的声明,搭配@synthesize使用
新:生成一个下划线开头成员变量,以及setter和getter的声明及实现
@synthesize
自动生成成员变量和属性的setter,getter实现

1
@synthesize dog = _dog;

@autorelease
系统会在恰当的时候进行释放

可以通过以下私有函数来查看自动释放池的情况

1
extern void _objc_autoreleasePoolPrint(void);

拷贝
产生一个副本对象,跟源对象不影响. 修改了源对象,不会影响副本对象;修改了副本对象,不会影响源对象。

iOS提供两种拷贝

  • copy 不可变拷贝,产生不可变副本
  • mutableCopy,可变拷贝,产生可变副本

深拷贝和浅拷贝

  • 浅拷贝:指针拷贝
    • 没有产生新对象
    • 引用计数+1
  • 深拷贝:内容拷贝
    • 产生新的对象。
    • 新的对象引用计数为1
copy mutableCopy
NSString NSString
浅拷贝
NSMutableString
深拷贝
NSMutableString NSString
深拷贝
NSMutableString
深拷贝
NSArray NSArray
浅拷贝
NSMutableArray
NSMutableArray NSArray
深拷贝
NSMutableArray
深拷贝
NSDictionary NSDictionary
浅拷贝
NSMutableDictionary
深拷贝
NSMutableDictionary NSDictionary
深拷贝
NSMutableDictionary
深拷贝

copy 并不代表浅拷贝。如果对一个可变对象做copy操作,那么其就是深拷贝。

MRC - 手动内存管理

当调用allocnewcopymutableCopy方法返回了一个对象,在不需要这个对象时,要调用release或者autorelease来释放它

复杂数据类型(retain,strong)的setter和getter

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
- (void)seDog:(Dog *)dog {
if (_dog != dog) {
[_dog release];
_dog = [dog retain];
}
}
- (Dog *)dog {
return _dog;
}
- (void)dealloc {
[_dog release];
_dog = nil;
// 或者
// self.dog = nil;
[super dealloc];
}

基础数据类型(assign)的setter和getter

1
2
3
4
5
6
- (void)seAge:(int)age {
_age = age;
}
- (int)age {
return _age;
}

涉及不到内存管理操作

遵循NSCoping协议类型(copy)的setter和getter

1
2
3
4
5
6
7
8
9
10
11
12
13
- (void)seName:(NSString *)name {
if (_name != name) {
[_name release];
_name = [name copy];
}
}
- (NSString *)name {
return _name;
}
- (void)dealloc {
[_name release];
[super dealloc];
}

遍历构造器
譬如[NSArray array]这种遍历构造器生成的对象,内部做了autorelease的处理,外部不需要再进行release操作

集合

copy

在OC中,只有NSDataNSStringNSSetNSArrayNSDictionary这些类支持copy操作。如果想对其他类实现copy操作,如下代码去实现
遵循NSCoping协议

1
<NSCoping>

实现协议方法

1
2
3
4
5
6
- (id)copyWithZone:(NSZone *)zone {
Person *person = [[Person alloc] init];
person.age = self.age;
person.name = self.name;
return person;
}
0%