目标

1.【理解】内存管理

2.【掌握】第一个MRC程序

3.【掌握】内存管理的原则

4.【理解】野指针与僵尸对象

5.【理解】单个对象的内存管理

6.【理解】多个对象的内存管理

7.【掌握】set方法的内存管理

8.【掌握】@property参数

9.【掌握】@class关键字

10.【理解】循环retain

一、内存管理

程序在运行过程中会在堆空间创建大量的对象,当对象不再使用的时候,系统并不会自动释放堆空间中的对象(基本数据类型是由系统自动管理的)。如果一个对象创建并使用后没有得到及时释放,那么这对象会直到程序结束才会被释放,这样就会占用大量内存空间。其他高级语言如C#、Java都是通过垃圾回收机制(GC)来解决这个问题的,但在OC中并没有类似的垃圾回收机制,因此它的内存管理就需要由程序员手动维护。并且栈空间、BSS段、数据段、代码段中的数据都是由系统自动管理的,所以这些区域的数据不需要由程序员来管理,我们只需要管理堆空间中的数据,也就是OC对象的释放需要我们来管理。

引用计数器

OC中内存的管理是依赖对象引用计数器来进行的,在OC中每个对象内部都有一个与之对应的整数(retainCount),叫“引用计数器”。当一个对象在创建之后它的引用计数器默认值为1,如果一个对象的引用计数器为0,则系统会自动调用这个对象的dealloc方法来销毁这个对象。

内存泄露

一个对象在使用完没有回收,直到程序结束的时候才被回收,这种现象就叫做内存泄露。

如何操作对象的引用计数器?

调用对象的retain方法,对象的引用计数器就会+1。

调用对象的release方法,对象的引用计数器就会-1。

调用对象的retainCount方法,就会得到这个对象的引用计数器的值。

总结:

当我们要使用一个对象的时候,应该为这个对象发送一条retain消息。当我们不再使用一个对象的时候,就应该为这个对象发送一条release消息。当对象的引用计数器为0的时候,系统就会调用这个对象的dealloc方法来销毁这个对象,所以我们一般会重写dealloc方法来监控对象的销毁。

二、第一个MRC程序

OC内存管理的分为MRC(Manual Reference Counting)手动引用计数ARC(Automatic Reference Counting)自动引用计数。见名知意,MRC是程序员自己手动记录对象的引用计数,而ARC则是系统自动记录对象的引用计数。由于ARC机制是在Xcode4.2后推出的,所以默认情况下Xcode是自动开启ARC机制的,我们要使用MRC就必须关闭ARC。

为了便于监控对象释放,我们经常需要重写dealloc方法。并且重写dealloc方法需要遵循一些规范,在子类的dealloc方法最后必须调用父类的dealloc方法。

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
//Person.h文件
#import <Foundation/Foundation.h>
 
@interface Person : NSObject
 
@end
 
//Person.m文件
#import "Person.h"
 
@implementation Person
 
//重写dealloc方法
- (void)dealloc {
    NSLog(@"人挂了...");
    
    //在子类dealloc方法最后必须调用父类dealloc方法
    [super dealloc];
}
@end
 
//main.m文件
#import <Foundation/Foundation.h>
#import "Person.h"
 
int main(int argc, const char * argv[]) {
    
    //使用alloc创建对象,默认对象引用计数器的值为 1
    Person *p = [[Person alloc] init];
    
    //给对象发送release消息只是让引用计数器 -1,并不是一定会让对象引用计数器变为0
    [p release];
    //调用对象的dealloc方法,输出
    //人挂了...
    return 0;
}

三、内存管理的原则

只在有人使用这个对象的时候才为对象发送retain消息,只在一个人不再使用对象的时候才为对象发送release消息。遵守谁创建谁release,谁retain谁release的原则。

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
//Person.h文件
#import <Foundation/Foundation.h>
 
@interface Person : NSObject
 
@end
 
//Person.m文件
#import "Person.h"
 
@implementation Person
 
//重写dealloc方法
- (void)dealloc {
    NSLog(@"人挂了...");
    
    //在子类dealloc方法最后必须调用父类dealloc方法
    [super dealloc];
}
@end
 
//main.m文件
#import <Foundation/Foundation.h>
#import "Person.h"
 
int main(int argc, const char * argv[]) {
    
    //使用alloc创建对象,引用计数器 +1
    Person *p = [[Person alloc] init];
    
    //给对象发送一条retain消息,引用计数器 +1
    [p retain];
    
    //给p对象发送一条retainCount消息,返回引用计数器的值
    NSUInteger count = [p retainCount];
    NSLog(@"count = %lu",count);
    
    //给对象发送release消息只是让引用计数器 -1,并不是一定会让对象引用计数器变为0
    [p release];
    
    //再发送一条release,此时引用计数器就为0了
    [p release];
    //调用对象的dealloc方法,输出
    //人挂了...了...
    return 0;
}

注意:

1.为对象发送release消息不是让对象释放,而是让对象的引用计数器-1。

2.当对象引用计数器的值为0时,系统会立即调用对象的dealloc方法释放对象。

3.创建谁release,谁retain谁release。

四、野指针与僵尸对象

C语言中的野指针:一个指针变量指向一块随机的内存空间,也就是未初始化的指针变量,这个指针就叫做野指针。

OC语言中的野指针:指针指向的对象已经被释放了,这个指针就叫做野指针。

僵尸对象:已经被释放的对象,叫做僵尸对象,也就是通过野指针访问的对象就是僵尸对象。注意一旦一个指针成为了野指针,就不要通过野指针去访问对象的成员了。

每次通过一个指针去访问一个对象的时候,都会去检查这个对象是否是僵尸对象,如果是就报错。默认情况下Xcode是不会自动检测僵尸对象,那么如何开启Xcode对僵尸对象的自动检测?

当一个对象被回收后,就为指向这个对象的指针赋值nil,可避免访问僵尸对象。

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
//Person.h文件
#import <Foundation/Foundation.h>
 
@interface Person : NSObject
 
- (void)eat;
@end
 
//Person.m文件
#import "Person.h"
 
@implementation Person
- (void)eat {
    NSLog(@"人吃饭");
}
//重写dealloc方法
- (void)dealloc {
    NSLog(@"人挂了...");
    //调用父类dealloc方法
    [super dealloc];
}
@end
 
//main.m文件
#import <Foundation/Foundation.h>
#import "Person.h"
 
int main(int argc, const char * argv[]) {
    Person *p = [[Person alloc] init];
    //release让引用计数器 -1,此时对象引用计数器为0.对象被销毁
    [p release];
    
    //p指针赋值nil
    p = nil;
    
    //给p对象发送消息不会报错,只会啥都不发生
    [p eat];
    return 0;
}

五、单个对象的内存管理

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#import <Foundation/Foundation.h>
#import "Person.h"
 
int main(int argc, const char * argv[]) {
    Person *p = [[Person alloc] init];//retainCount == 1
    [p retain];//retainCount == 2
    [p retain];//retainCount == 3
 
//    //只有retain没有release
    [p release];//retainCount == 2
    [p release];//retainCount == 1
    
//    //在不适当的时候为指针赋值nil
//    p = nil;//对象还没释放,就将指针赋值nil
    [p release];//retainCount == 0
    return 0;
}

六、多个对象的内存管理

当一个对象的属性是另一个对象的时候,在这个属性的setter方法中,将传入的对象先retain一次,再赋值给属性。并在dealloc方法中对属性进行一次release。

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
//Car.h文件
#import <Foundation/Foundation.h>
 
@interface Car : NSObject
 
- (void)run;
@end
 
//Car.m文件
#import "Car.h"
 
@implementation Car
-(void)run {
    NSLog(@"车启动");
}
 
- (void)dealloc {
    NSLog(@"车挂了...");
    
    //调用父类dealloc方法
    [super dealloc];
}
@end
 
//Person.h文件
#import <Foundation/Foundation.h>
#import "Car.h"
 
@interface Person : NSObject
@property Car *car;
 
- (void)drive;
@end
 
//Person.m文件
#import "Person.h"
 
@implementation Person
 
- (void)setCar:(Car *)car {
    //retain传入的对象,因为多了一个指针(_car属性)指向这个传入的对象
    //retain返回值是对象本身
    _car = [car retain];
}
 
- (void)drive {
    NSLog(@"车启动");
    //调用_car的run方法
    [self.car run];
}
 
- (void)dealloc {
    NSLog(@"人挂了...");
    //在人挂的时候让车也挂
    [self.car release];
    
    //调用父类dealloc方法
    [super dealloc];
}
@end
 
//main.m文件
#import <Foundation/Foundation.h>
#import "Person.h"
 
int main(int argc, const char * argv[]) {
    //实例化人和车对象
    Person *p = [[Person alloc] init];
    Car *bmw = [[Car alloc] init];
    
    //给人一辆车
    p.car = bmw;
    
    //后创建的对象先release
    [bmw release];
    bmw = nil;
 
    [p release];
    p = nil;
    return 0;
}

七、set方法的内存管理

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
//Car.h文件
#import <Foundation/Foundation.h>
 
@interface Car : NSObject
@property int speed;
 
- (void)run;
@end
 
//Car.m文件
#import "Car.h"
 
@implementation Car
-(void)run {
    NSLog(@"车启动");
}
 
- (void)dealloc {
    NSLog(@"时速为%d车挂了...",_speed);
    
    [super dealloc];
}
@end
 
//Person.h文件
#import <Foundation/Foundation.h>
#import "Car.h"
 
@interface Person : NSObject
@property Car *car;
@property NSString *name;
- (void)drive;
@end
 
//Person.m文件
#import "Person.h"
 
@implementation Person
 
- (void)setCar:(Car *)car {
    //判断传入对象是否和属性的旧值是同一对象
    if (_car != car) {
        //不是同一对象就release旧值
        [_car release];
        //retain新值
        _car = [car retain];
    }
}
 
- (void)drive {
    //调用_car的run方法
    [_car run];
}
 
- (void)dealloc {
    NSLog(@"%@挂了...",_name);
    //对象释放前将属性指向的对象release一次,表示不指向那个对象了
    [_car release];
    
    [super dealloc];
}
@end
 
//main.m文件
#import <Foundation/Foundation.h>
#import "Person.h"
 
int main(int argc, const char * argv[]) {
    //实例化两个人对象
    Person *p1 = [[Person alloc] init];//p1的retainCount == 1
    Person *p2 = [[Person alloc] init];//p2的retainCount == 1
    //分别为两个人对象的_name赋值
    p1.name = @"jack";
    p2.name = @"rose";
    
    //实例化两个车对象
    Car *bmw = [[Car alloc] init];//bmw的retainCount == 1
    Car *benz = [[Car alloc] init];//benz的retainCount == 1
    //分别为两个车对象的_speed赋值
    bmw.speed = 100;
    benz.speed = 80;
    
    //p1指向bmw
    p1.car = bmw;//bmw的retainCount == 2
    
    //p2也指向bmw
    p2.car = bmw;//bmw的retainCount == 3
    
    //p2不指向bmw了,指向benz
    p2.car = benz;//bmw的retainCount == 2 , benz的retainCount == 2
    
    [benz release];//benz的retainCount == 1
    [p2 release];//p2的retainCount == 0 调用了p2的delloc方法,再调用benz的release. benz的retainCount == 0  所以rose挂了,benz也挂了
    [bmw release];//bmw的retainCount == 1
    [p1 release];//p1的retainCount == 0 调用了p1的delloc方法,再调用bmw的release. bmw的retainCount == 0  所以jack挂了,bmw也挂了
    
    /* 输出
    rose挂了...
    时速为80车挂了...
    jack挂了...
    时速为100车挂了...
     */
    return 0;
}

八、@property参数

@property的参数分为三类,中间用逗号分隔,每类参数可以从上图三类参数中任选一个。如果不进行设置或者只设置其中一类参数,程序会使用三类中的各类的默认参数,默认参数:(atomic,readwrite,assign)。

格式:@property ([参数1,参数2,参数3]) 数据类型 名称;    // []里表示可选

一般情况下如果在多线程开发中一个属性可能会被两个及两个以上的线程同时访问,此时可以考虑atomic属性,否则建议使用nonatomic,不加锁,效率较高。readwirte方法会生成getter、setter两个方法,如果使用readonly则只生成getter方法。关于setter方法处理需要特别说明,假设我们定义一个属性a,这里列出三种方式的生成代码:

assign,用于基本数据类型

 
1
2
3
- (void)setA:(int)a {
    _a = a;
}

retain,通常用于非字符串对象

 
1
2
3
4
5
6
- (void)setA:(Car *)a {
    if(_a != a){
        [_a release];
        _a = [a retain];
    }
}

copy,通常用于字符串对象

 
1
2
3
4
5
6
- (void)setA:(NSString *)a{
    if(_a != a){
        [_a release];
        _a = [a copy];
    }
}

我们可以在参数中指定@property生成的setter、getter的方法名称,一般情况下,当属性的类型是一个BOOL类型的时候,我们可以指定getter方法名以is开头,这样增强代码可阅读性。

 
1
2
3
4
5
6
7
8
9
10
11
12
13
@property (nonatomic,assign,readwrite,getter=isRich) int rich;
 
//生成的setter、getter方法声明
- (void)setRich:(BOOL)rich;
- (BOOL)isRich;
 
//生成的setter、getter方法实现
- (void)setRich:(BOOL)rich {
    
}
- (BOOL)isRich {
 
}

实际应用案例

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
//Book.h文件
#import <Foundation/Foundation.h>
 
@interface Book : NSObject
@property (nonatomic, copy) NSString *bookName;
@end
 
//Book.m文件
#import "Book.h"
 
@implementation Book
- (void)dealloc {
    NSLog(@"<<%@>>被烧了",_bookName);
    [_bookName release];
    
    [super dealloc];
}
@end
 
//Student.h文件
#import <Foundation/Foundation.h>
#import "Book.h"
 
@interface Student : NSObject
@property (nonatomic, retain) Book *book;
@end
 
//Student.m文件
#import "Student.h"
 
@implementation Student
- (void)dealloc {
    
    NSLog(@"<<%@>>",_book.bookName);
    [_book release];
    
    [super dealloc];
}
@end
 
//main.m文件
#import <Foundation/Foundation.h>
#import "Student.h"
 
int main(int argc, const char * argv[]) {
    Student *stu = [[Student alloc] init];//stu的retainCount == 1
    Book *book = [[Book alloc] init];//book的retainCount == 1
    
    stu.book = book;//book的retainCount == 2
    stu.book.bookName = @"风流少女";
    
    [book release];//book的retainCount == 1
    [stu release];//stu的retainCount == 0,调用stu的dealloc方法,再调用book的release,则book的retainCount == 0
    
    /*
     输出
     学生挂了
     <<风流少女>>被烧了
     */
    return 0;
}

九、@class关键字

当两个类相互包含的时候,就会造成死循环。在.h文件中不能包含和自己关联的那个类的头文件,因为一旦包含就会造成死循环。应该使用@class来声明一个类存在,如果在.m文件中需要使用用@class声明的类的成员时,就在.m文件中包含即可。

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
//Book.h文件
#import <Foundation/Foundation.h>
@class Student;//如果不需要使用类中的成员可以使用@class告诉编译器,Student是一个类
 
@interface Book : NSObject
@property (nonatomic, copy) NSString *bookName;
@property (nonatomic, assign) Student *owner;
 
- (void)showOwner;
@end
 
//Book.m文件
#import "Book.h"
#import "Student.h"
 
@implementation Book
- (void)showOwner {
    //使用了Student类的成员_name,直接包含头文件即可
    NSLog(@"%@的主人是%@",self.bookName,self.owner.name);
}
- (void)dealloc {
    NSLog(@"书挂");
    [_bookName release];
    [super dealloc];
}
@end
 
//Student.h文件
#import <Foundation/Foundation.h>
@class Book;//如果不需要使用类中的成员可以使用@class告诉编译器,Book是一个类
 
@interface Student : NSObject
@property (nonatomic, copy) NSString *name;
@property (nonatomic, retain) Book *book;
 
- (void)showBook;
@end
 
//Student.m文件
#import "Student.h"
#import "Book.h"
 
@implementation Student
- (void)showBook {
    //使用了Book类的成员_bookName,直接包含头文件即可
    NSLog(@"%@的书名叫%@",self.name,self.Book.bookName);
}
- (void)dealloc {
    NSLog(@"学生挂");
    [_name release];
    [_book release];
    [super dealloc];
}
@end

十、循环retain

当两个类互相引用的时候,如果两个类的@property的参数都是retain就会出现循环引用造成内存泄露。解决办法是一个类使用retain,另一个类使用assign。使用assign的类不用在dealloc方法中对那个属性release。

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
//Book.h文件
#import <Foundation/Foundation.h>
@class Student;//告诉Book,Student是一个类
 
@interface Book : NSObject
@property (nonatomic, copy) NSString *bookName;
@property (nonatomic, assign) Student *owner;//使用assign
 
@end
 
//Book.m文件
#import "Book.h"
 
@implementation Book
 
- (void)dealloc {
    NSLog(@"<<%@>>释放",self.bookName);
    [super dealloc];
}
@end
 
//Student.h文件
#import <Foundation/Foundation.h>
@class Book;//告诉Student,Book是一个类
 
@interface Student : NSObject
@property (nonatomic, copy) NSString *name;
@property (nonatomic, retain) Book *book;//使用retain
 
@end
 
//Student.m文件
#import "Student.h"
 
@implementation Student
 
- (void)dealloc {
    NSLog(@"<<%@>>释放了",self.name);
    [_book release];
    [super dealloc];
}
@end
 
//main.m文件
#import <Foundation/Foundation.h>
#import "Book.h"
#import "Student.h"
 
int main(int argc, const char * argv[]) {
    Book *book = [[Book alloc] init];//book的retainCount == 1
    book.bookName = @"风流少女";
    
    Student *student = [[Student alloc] init];//student的retainCount == 1
    student.name = @"牛逼哥";
    
    book.owner = student;//因为是assign,所以不会retain传入的student,则student的retainCount == 1
    student.book = book;//因为是retain,会retain传入的book,则book的retainCount == 2
    
    [student release];//student的retainCount == 0,会调用student的dealloc方法,再调用一次book的release。则book的retainCount == 1
    student = nil;
    
    [book release];//book的retainCount == 0
    book = nil;
    
    /* 输出
     <<牛逼哥>>释放了
     <<风流少女>>释放
     */
    return 0;
}

iOS-OC内存管理的更多相关文章

  1. iOS - OC 内存管理

    1.OC 基本内存管理模型 1.1 自动垃圾收集 在 OC 2.0 中,有一种称为垃圾收集的内存管理形式.通过垃圾收集,系统能够自动监测对象是否拥有其他的对象,当程序执行需要空间的时候,不再被引用的对 ...

  2. iOS学习17之OC内存管理

    1.内存管理的方式 1> iOS应用程序出现Crash(闪退),90%的原因是因为内存问题. 2> 内存问题 野指针异常:访问没有所有权的内存,如果想要安全的访问,必须确保空间还在 内存泄 ...

  3. 【0 - 1】OC内存管理

    一.内存管理概述 垃圾回收机制(GC):由系统管理内存,程序员不需要管理. OC中的垃圾回收:在OC2.0版加入垃圾回收. OC与iOS:OC有垃圾回收机制,但是iOS屏蔽了这个功能.原因:iOS运行 ...

  4. OC 内存管理机制总结

    OC 内存管理机制总结 一:OC内存管理机制目前分为两块,其一自动内存管理机制,其二手动内存管理机制: 1.首先我们从自动内存管理机制讲起: 1)什么是自动内存管理机制,自动内存管理机制就是程序中所创 ...

  5. iOS之内存管理(ARC)

    iOS的内存管理,相信大家都不陌生,之前是使用的MRC,由开发人员手动来管理内存,后来使用了ARC,来由系统管理内存.本文主要讲讲Autorelease,Core Foundation对象在内存管理方 ...

  6. OC内存管理总结,清晰明了!

    <span style="font-size:18px;">OC内存管理 一.基本原理 (一)为什么要进行内存管理. 由于移动设备的内存极其有限.所以每一个APP所占的 ...

  7. iOS的内存管理和引用计数规则、Block的用法以及三种形式(stack、malloc、global)

    学习内容 iOS的内存管理和引用计数规则 内存管理的思考方式 自己生成的对象自己持有 非自己生成的对象自己也能持有 自己持有的对象不需要时释放 非自己持有的对象不能释放 ARC有效时,id类型和对象类 ...

  8. 理解 iOS 的内存管理

    远古时代的故事 那些经历过手工管理内存(MRC)时代的人们,一定对 iOS 开发中的内存管理记忆犹新.那个时候大约是 2010 年,国内 iOS 开发刚刚兴起,tinyfool 大叔的大名已经如雷贯耳 ...

  9. iOS ARC内存管理

    iOS的内存管理机制,只要是iOS开发者,不管多长的时间经验,都能说出来一点,但是要深入的理解.还是不简单的.随着ARC(自动管理内存)的流行.iOS开发者告别了手动管理内存的复杂工作.但是自动管理内 ...

  10. OC内存管理基础

    OC 内存管理基础 一. retain和release基本使用 使用注意: 1.你想使用(占用)某个对象,就应该让对象的计数器+1(让对象做一次retain操作) 2.你不想再使用(占用)某个对象,就 ...

随机推荐

  1. java文件乱码

    要让一个 Java 源文件打开时编码格式为 UTF-8,需要做2件事情:1)设置Java 源文件的默认编码格式为UTF-8:2)设置workspace的编码格式为UTF-8. 相应设置如下: 设置 J ...

  2. MATLAB - 练习程序,求灰度图像均值、最大、最小数值

    clear all; close all; clc img=imread('lena.bmp'); figure; imshow(uint8(img)); [m n]=size(img); img_m ...

  3. elasticsearch Java API汇总

    http://blog.csdn.net/changong28/article/details/38445805#comments 3.1 集群的连接 3.1.1 作为Elasticsearch节点 ...

  4. HDOJ 4508 湫湫系列故事——减肥记I (完全背包带优化)

    完全背包的模版题.. 加了一个小优化  n^2的写法 O(V+N)在本题中复杂度较高 不采纳 完全背包问题有一个很简单有效的优化,是这样的:若两件物品i.j满足c[i]<=c[j]且w[i]&g ...

  5. Train Problem I hdu 1022(栈)

    http://acm.split.hdu.edu.cn/showproblem.php?pid=1022 题意:给出火车的进站与出站顺序,判断是否可以按照给出的出站顺序出站. #include < ...

  6. sql 返回xml类型的数据

    1, 这中方式可以在Item节点上加一个Items节点作为所有item节点的父节点 SELECT  Orders.OrderNumber ,        ( SELECT    ProductID ...

  7. iOS.OpenSource.AllInOne

    Open Source Project for iOS 所有和iOS相关的Open Source Project的汇总. 功能点 开源项目   iOS Gallery RMGallery https: ...

  8. RNN and LSTM saliency Predection Scene Label

    http://handong1587.github.io/deep_learning/2015/10/09/rnn-and-lstm.html  //RNN and LSTM http://hando ...

  9. jquery 让select元素中的某个option被选中

    jquery 操作select 取值,设置选中值 博客分类: javaScript selecttextvalue取值设置选中值 比如 <select class="type" ...

  10. zlog使用

    1.使用buildroot编译zlog,在工具链的系统根目录下会生成动态库和静态库,还添加了头文件. 2.把动态库拷贝到开发板文件系统(该文件系统可以不是由buildroot编译得到,而是板上自带的) ...