KVC和KVO

OC中的一个比较有特色的知识点:KVC和KVO

一、KVC操作
OC中的KVC操作就和Java中使用反射机制去访问类的private权限的变量,很暴力的,这样做就会破坏类的封装性,本来类中的的private权限就是不希望外界去访问的,但是我们这样去操作,就会反其道而行,但是我们有时候真的需要去这样做,哎。所以说有些事不是都是顺其自然的,而是需要的时候自然就诞生了。
下面就来看一下这种技术的使用:
Dog.h
[objc]  view plaincopy
1. //  
2. //  Dog.h  
3. //  42_KVC  
4. //  
5. //  Created by jiangwei on 14-10-14.  
6. //  Copyright (c) 2014年 jiangwei. All rights reserved.  
7. //  
8.   
9. #import <Foundation/Foundation.h>  
10.   
11. @interface Dog : NSObject  
12.   
13. @end  


Dog.m
[objc]  view plaincopy
1. //  
2. //  Dog.m  
3. //  42_KVC  
4. //  
5. //  Created by jiangwei on 14-10-14.  
6. //  Copyright (c) 2014年 jiangwei. All rights reserved.  
7. //  
8.   
9. #import "Dog.h"  
10.   
11. @implementation Dog  
12.   
13. @end  
定义了Dog这个类,但是什么都没有,他只是一个中间类,没什么作用,在这个demo中。


Person.h
[objc]  view plaincopy
1. //  
2. //  Person.h  
3. //  42_KVC  
4. //  
5. //  Created by jiangwei on 14-10-14.  
6. //  Copyright (c) 2014年 jiangwei. All rights reserved.  
7. //  
8.   
9. #import <Foundation/Foundation.h>  
10. #import "Dog.h"  
11.   
12. @interface Person : NSObject{  
13. @private  
14.     NSString *_name;  
15.     NSDog *_dog;  
16.       
17.     NSInteger *age;  
18. }  
19.   
20. @end  


Person.m
[objc]  view plaincopy
1. //  
2. //  Person.m  
3. //  42_KVC  
4. //  
5. //  Created by jiangwei on 14-10-14.  
6. //  Copyright (c) 2014年 jiangwei. All rights reserved.  
7. //  
8.   
9. #import "Person.h"  
10.   
11. @implementation Person  
12.   
13. - (NSString *)description{  
14.     NSLog(@"%@",_name);  
15.     return _name;  
16. }  
17.   
18. @end  
Person类中我们定义了两个属性,但是这两个属性对外是不可访问的,而且也没有对应的get/set方法。我们也实现了description方法,用于打印结果


看一下测试代码
main.m
[objc]  view plaincopy
1. //  
2. //  main.m  
3. //  42_KVC  
4. //  
5. //  Created by jiangwei on 14-10-14.  
6. //  Copyright (c) 2014年 jiangwei. All rights reserved.  
7. //  
8.   
9. #import <Foundation/Foundation.h>  
10. #import "Person.h"  
11. #import "Dog.h"  
12.   
13. //KVC:很暴力,及时一个类的属性是私有的,而且也没有get/set方法,同样可以读写  
14. //相当于Java中的反射,破坏类的封装性  
15. int main(int argc, const charchar * argv[]) {  
16.     @autoreleasepool {  
17.           
18.         Person *p = [[Person alloc] init];  
19.           
20.         //设置值  
21.         //这里setValue方法:第一个参数是value,第二个参数是key(就是类的属性名称)  
22.         [p setValue:@"jiangwei" forKey:@"name"];  
23.           
24.         Dog *dog = [[Dog alloc] init];  
25.         [p setValue:dog forKey:@"dog"];  
26.           
27.         //KVC设置值时,如果属性有set方法,则优先调用set方法,如果没有则直接设置上去,get方法类似  
28.           
29.         //读取值  
30.         NSString *name = [p valueForKey:@"name"];  
31.           
32.         //设置基本数据类型  
33.         //这里需要将基本类型转化成NSNumber  
34.         //在设置值的时候,会有自动解包的过程,NSNumber会解包赋值给age  
35.         [p setValue:@22 forKey:@"age"];  
36.           
37.         NSLog(@"%@",p);  
38.           
39.         return 0;  
40.     }  
41.     return 0;  
42. }  
这里我们生成一个Person对象,然后开始使用KVC技术了:


1、设置属性值
[java]  view plaincopy
1. //设置值  
2. //这里setValue方法:第一个参数是value,第二个参数是key(就是类的属性名称)  
3. [p setValue:@"jiangwei" forKey:@"name"];  
4.           
5. Dog *dog = [[Dog alloc] init];  
6. [p setValue:dog forKey:@"dog"];  
使用setValue方法,就可以进行对属性进行设置值操作了,同时需要传递这个属性的名称,这个和Java中使用反射机制真的很像。
注:KVC设置值时,如果属性有set方法,则优先调用set方法,如果没有则直接设置上去,get方法一样
[java]  view plaincopy
1. //设置基本数据类型  
2. //这里需要将基本类型转化成NSNumber  
3. //在设置值的时候,会有自动解包的过程,NSNumber会解包赋值给age  
4. [p setValue:@22 forKey:@"age"];  
还有一个需要注意的地方:当我们在设置基本类型的时候,需要将其转化成NSNumber类型的。


2、取属性的值
[java]  view plaincopy
1. //读取值  
2. NSString *name = [p valueForKey:@"name"];  
取值就简单了

下面再来看一下KVC中强大的功能:键值路径
键值路径是对于一个类中有数组对象的属性进行便捷操作。
看个场景:
一个作者有多本书
Author.h
[objc]  view plaincopy
1. //  
2. //  Author.h  
3. //  43_KeyValuePath  
4. //  
5. //  Created by jiangwei on 14-10-15.  
6. //  Copyright (c) 2014年 jiangwei. All rights reserved.  
7. //  
8.   
9. #import <Foundation/Foundation.h>  
10.   
11. @interface Author : NSObject{  
12.     NSString *_name;  
13.       
14.     //作者出版的书,一个作者对应多个书籍对象  
15.     NSArray *_issueBook;  
16. }  
17.   
18. @end  
作者类中定义了名字和一个书籍数组

Author.m
[objc]  view plaincopy
1. //  
2. //  Author.m  
3. //  43_KeyValuePath  
4. //  
5. //  Created by jiangwei on 14-10-15.  
6. //  Copyright (c) 2014年 jiangwei. All rights reserved.  
7. //  
8.   
9. #import "Author.h"  
10.   
11. @implementation Author  
12.   
13. @end  

Book.h
[objc]  view plaincopy
1. //  
2. //  Book.h  
3. //  43_KeyValuePath  
4. //  
5. //  Created by jiangwei on 14-10-15.  
6. //  Copyright (c) 2014年 jiangwei. All rights reserved.  
7. //  
8.   
9. #import <Foundation/Foundation.h>  
10. #import "Author.h"  
11.   
12. @interface Book : NSObject{  
13.     Author *_author;  
14. }  
15.   
16. @property NSString *name;  
17. @property floatfloat *price;  
18.   
19. @end  
定义了一个作者属性,书的名字,价格

Book.m
[objc]  view plaincopy
1. //  
2. //  Book.m  
3. //  43_KeyValuePath  
4. //  
5. //  Created by jiangwei on 14-10-15.  
6. //  Copyright (c) 2014年 jiangwei. All rights reserved.  
7. //  
8.   
9. #import "Book.h"  
10.   
11. @implementation Book  
12.   
13. @end  

看一下测试代码
main.m
[objc]  view plaincopy
1. //  
2. //  main.m  
3. //  43_KeyValuePath  
4. //  
5. //  Created by jiangwei on 14-10-15.  
6. //  Copyright (c) 2014年 jiangwei. All rights reserved.  
7. //  
8.   
9. #import <Foundation/Foundation.h>  
10. #import "Book.h"  
11. #import "Author.h"  
12.   
13. int main(int argc, const charchar * argv[]) {  
14.     @autoreleasepool {  
15.           
16.         //------------------KVC键值路径  
17.         /* 
18.         Book *book = [[Book alloc] init]; 
19.         Author *author = [[Author alloc] init]; 
20.          
21.         //设置作者 
22.         [book setValue:author forKey:@"author"]; 
23.          
24.         //设置作者的名字 
25.         //路径为:author.name,中间用点号进行连接 
26.         [book setValue:@"jiangwei" forKeyPath:@"author.name"]; 
27.         NSString *name = [author valueForKey:@"name"]; 
28.         NSLog(@"name is %@",name); 
29.          */  
30.           
31.           
32.         //--------------------KVC的运算  
33.         Author *author = [[Author alloc] init];  
34.         [author setValue:@"莫言" forKeyPath:@"name"];  
35.           
36.         Book *book1 = [[Book alloc] init];  
37.         book1.name = @"红高粱";  
38.         book1.price = 9;  
39.         Book *book2 = [[Book alloc] init];  
40.         book2.name = @"蛙";  
41.         book2.price = 10;  
42.         NSArray *array = [NSArray arrayWithObjects:book1,book2, nil nil];  
43.         [author setValue:array forKeyPath:@"issueBook"];  
44.           
45.         //基本数据类型会自动被包装成NSNumber,装到数组中  
46.         //得到所有书籍的价格  
47.         NSArray *priceArray = [author valueForKeyPath:@"issueBook.price"];  
48.         NSLog(@"%@",priceArray);  
49.           
50.         //获取数组的大小  
51.         NSNumber *count = [author valueForKeyPath:@"issueBook.@count"];  
52.         NSLog(@"count=%@",count);  
53.           
54.         //获取书籍价格的总和  
55.         NSNumber *sum = [author valueForKeyPath:@"issueBook.@sum.price"];  
56.         NSLog(@"%@",sum);  
57.           
58.         //获取书籍的平均值  
59.         NSNumber *avg = [author valueForKeyPath:@"issueBook.@avg.price"];  
60.         NSLog(@"%@",avg);  
61.           
62.         //获取书籍的价格最大值和最小值  
63.         NSNumber *max = [author valueForKeyPath:@"issueBook.@max.price"];  
64.         NSNumber *min = [author valueForKeyPath:@"issueBook.@min.price"];  
65.           
66.     }  
67.     return 0;  
68. }  

1、首先通过前面说到的KVC设置作者的书籍数组
[objc]  view plaincopy
1. //--------------------KVC的运算  
2. Author *author = [[Author alloc] init];  
3. [author setValue:@"莫言" forKeyPath:@"name"];  
4.   
5. Book *book1 = [[Book alloc] init];  
6. book1.name = @"红高粱";  
7. book1.price = 9;  
8. Book *book2 = [[Book alloc] init];  
9. book2.name = @"蛙";  
10. book2.price = 10;  
11. NSArray *array = [NSArray arrayWithObjects:book1,book2, nil nil];  
12. [author setValue:array forKeyPath:@"issueBook"];  
添加了两本书籍

2、下面就开始用到KVC中键值路径了
1)获取作者类中书籍数组中所有书籍的价格
[java]  view plaincopy
1. //基本数据类型会自动被包装成NSNumber,装到数组中  
2. //得到所有书籍的价格  
3. NSArray *priceArray = [author valueForKeyPath:@"issueBook.price"];  
4. NSLog(@"%@",priceArray);  
看到了:@"issueBook.price" 这就是键值路径的使用,issueBook是作者类中的书籍数组属性名,price是书籍类的属性,中间用点号进行连接,这样我们就可以获取到了所有书籍的价格了,如果在Java中,我们需要用一个循环操作。但是OC中多么方便。

2)获取作者类中书籍数组的大小
[java]  view plaincopy
1. //获取数组的大小  
2. NSNumber *count = [author valueForKeyPath:@"issueBook.@count"];  
3. NSLog(@"count=%@",count);  
使用 @"issueBook.@count" 键值路径获取书籍数组的大小,issueBook是作者类中的书籍数组属性名,@count是特定一个写法,可以把它想象成一个方法,中间任然用点号进行连接

3)获取作者类中书籍数组的价格总和
[java]  view plaincopy
1. //获取书籍价格的总和  
2. NSNumber *sum = [author valueForKeyPath:@"issueBook.@sum.price"];  
3. NSLog(@"%@",sum);  
使用 @"issueBook.@sum.price" 键值路径获取书籍数组中的价格总和,issueBook是作者类中的书籍数组属性名,@sum是特性写法,可以把它想象成一个方法,price是书籍的价格属性名,可以把它看成是@sum的一个参数,中间用点号进行连接
如果在java中,这个需要用一个循环来计算总和,OC中很方便的

4)获取作者类中书籍数组的价格平均值、最小值、最大值
[objc]  view plaincopy
1. //获取书籍的平均值  
2. NSNumber *avg = [author valueForKeyPath:@"issueBook.@avg.price"];  
3. NSLog(@"%@",avg);  
4.   
5. //获取书籍的价格最大值和最小值  
6. NSNumber *max = [author valueForKeyPath:@"issueBook.@max.price"];  
7. NSNumber *min = [author valueForKeyPath:@"issueBook.@min.price"];  
操作和上面类似,这里就不解释了

我们看到上面返回来的数据都是NSNumber类型的

二、KVO操作
KVO操作在OC中也是经常会用到的,而且这种机制在java中不存在的。
它的作用就是用来监听类中属性值的变化,实现原理是观察者模式,当然我们也可以使用观察者模式在Java中实现这样的机制
看一下具体的例子:现在有一个小孩类,他有两个属性:开心值,饥饿值,然后还有一个护士类,用来监听孩子类的这两个属性值的
Chidren.h
[objc]  view plaincopy
1. //  
2. //  Children.h  
3. //  44_KVO  
4. //  
5. //  Created by jiangwei on 14-10-16.  
6. //  Copyright (c) 2014年 jiangwei. All rights reserved.  
7. //  
8.   
9. #import <Foundation/Foundation.h>  
10.   
11. @interface Children : NSObject  
12.   
13. @property NSInteger *hapyValue;  
14. @property NSInteger *hurryValue;  
15.   
16.   
17. @end  

Children.m
[objc]  view plaincopy
1. //  
2. //  Children.m  
3. //  44_KVO  
4. //  
5. //  Created by jiangwei on 14-10-16.  
6. //  Copyright (c) 2014年 jiangwei. All rights reserved.  
7. //  
8.   
9. #import "Children.h"  
10.   
11. @implementation Children  
12.   
13. - (id) init{  
14.     self = [super init];  
15.     if(self != nil){  
16.         //启动定时器  
17.         [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(timerAction) userInfo:nil repeats:YES];  
18.         self.hapyValue= 100;  
19.     }  
20.     return self;  
21. }  
22.   
23. - (void) timerAction:(NSTimer *) timer{  
24.     //使用set方法修改属性值,才能触发KVO  
25.       
26.     int value = _hapyValue;  
27.     [self setHapyValue:--value];  
28.       
29.     int values = _hurryValue;  
30.     [self setHurryValue:--values];  
31. }  
32.   
33.   
34. @end  
在初始化方法中,我们启动一个定时器,然后隔1s就去修改孩子类的值

Nure.h
[objc]  view plaincopy
1. //  
2. //  Nure.h  
3. //  44_KVO  
4. //  
5. //  Created by jiangwei on 14-10-16.  
6. //  Copyright (c) 2014年 jiangwei. All rights reserved.  
7. //  
8.   
9. #import <Foundation/Foundation.h>  
10.   
11. @class Children;  
12. @interface Nure : NSObject{  
13.     Children *_children;  
14. }  
15.   
16. - (id) initWithChildren:(Children *)children;  
17.   
18. @end  
定义一个孩子属性


Nure.m
[objc]  view plaincopy
1. //  
2. //  Nure.m  
3. //  44_KVO  
4. //  
5. //  Created by jiangwei on 14-10-16.  
6. //  Copyright (c) 2014年 jiangwei. All rights reserved.  
7. //  
8.   
9. #import "Nure.h"  
10. #import "Children.h"  
11.   
12. @implementation Nure  
13.   
14. - (id) initWithChildren:(Children *)children{  
15.     self = [super init];  
16.     if(self != nil){  
17.         _children = children;  
18.           
19.         //观察小孩的hapyValue  
20.         //使用KVO为_children对象添加一个观察者,用于观察监听hapyValue属性值是否被修改  
21.         [_children addObserver:self forKeyPath:@"hapyValue" options:NSKeyValueObservingOptionNew |NSKeyValueObservingOptionOld context:@"context"];  
22.           
23.         //观察小孩的hurryValue  
24.         [_children addObserver:self forKeyPath:@"hurryValue" options:NSKeyValueObservingOptionNew |NSKeyValueObservingOptionOld context:@"context"];  
25.     }  
26.     return self;  
27. }  
28.   
29. //触发方法  
30. - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(voidvoid *)context{  
31.     NSLog(@"%@",change);  
32.     //通过打印change,我们可以看到对应的key  
33.       
34.     //通过keyPath来判断不同属性的观察者  
35.     if([keyPath isEqualToString:@"hapyValue"]){  
36.         //这里change中有old和new的值是因为我们在调用addObserver方法时,用到了  
37.         //NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld;想要哪一个就用哪一个  
38.         //[change objectForKey:@"old"]是修改前的值  
39.         NSNumber *hapyValue = [change objectForKey:@"new"];//修改之后的最新值  
40.           
41.         NSInteger *value = [hapyValue integerValue];  
42.           
43.         if(value < 90){  
44.             //do something...  
45.         }  
46.     }else if([keyPath isEqualToString:@"hurryValue"]){  
47.         //这里change中有old和new的值是因为我们在调用addObserver方法时,用到了  
48.         //NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld;想要哪一个就用哪一个  
49.         //[change objectForKey:@"old"]是修改前的值  
50.         NSNumber *hurryValue = [change objectForKey:@"new"];//修改之后的最新值  
51.           
52.         NSInteger *value = [hurryValue integerValue];  
53.           
54.         if(value < 90){  
55.             //do something...  
56.         }  
57.     }  
58.       
59.     NSLog(@"%@",context);//打印的就是addObserver方法的context参数  
60.       
61.       
62.       
63.     //使用KVC去修改属性的值,也会触发事件  
64. }  
65.   
66. - (void)dealloc{  
67.       
68.     //移除观察者  
69.     [_children removeObserver:self forKeyPath:@"hapyValue"];  
70.     [_children removeObserver:self forKeyPath:@"hurryValue"];  
71.       
72. }  
73.   
74. @end  
看到了在这里就开始进行监听操作了

下面来具体看一下如何做到监听的
1、添加监听对象
我们使用addObserver方法给孩子添加监听对象
第一个参数:监听者,这里是Nure,所以可以直接传递self
第二个参数:监听对象的属性名
第三个参数:监听这个属性的状态:这里可以使用|进行多种组合操作,属性的新值和旧值
第四个参数:传递内容给监听方法
[java]  view plaincopy
1. //观察小孩的hapyValue  
2. //使用KVO为_children对象添加一个观察者,用于观察监听hapyValue属性值是否被修改  
3. [_children addObserver:self forKeyPath:@"hapyValue" options:NSKeyValueObservingOptionNew |NSKeyValueObservingOptionOld context:@"context"];  
4.   
5. //观察小孩的hurryValue  
6. [_children addObserver:self forKeyPath:@"hurryValue" options:NSKeyValueObservingOptionNew |NSKeyValueObservingOptionOld context:@"context"];  

2、监听方法
[objc]  view plaincopy
1. //触发方法  
2. - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(voidvoid *)context{  
3.     NSLog(@"%@",change);  
4.     //通过打印change,我们可以看到对应的key  
5.       
6.     //通过keyPath来判断不同属性的观察者  
7.     if([keyPath isEqualToString:@"hapyValue"]){  
8.         //这里change中有old和new的值是因为我们在调用addObserver方法时,用到了  
9.         //NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld;想要哪一个就用哪一个  
10.         //[change objectForKey:@"old"]是修改前的值  
11.         NSNumber *hapyValue = [change objectForKey:@"new"];//修改之后的最新值  
12.           
13.         NSInteger *value = [hapyValue integerValue];  
14.           
15.         if(value < 90){  
16.             //do something...  
17.         }  
18.     }else if([keyPath isEqualToString:@"hurryValue"]){  
19.         //这里change中有old和new的值是因为我们在调用addObserver方法时,用到了  
20.         //NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld;想要哪一个就用哪一个  
21.         //[change objectForKey:@"old"]是修改前的值  
22.         NSNumber *hurryValue = [change objectForKey:@"new"];//修改之后的最新值  
23.           
24.         NSInteger *value = [hurryValue integerValue];  
25.           
26.         if(value < 90){  
27.             //do something...  
28.         }  
29.     }  
30.       
31.     NSLog(@"%@",context);//打印的就是addObserver方法的context参数  
32.       
33.       
34.       
35.     //使用KVC去修改属性的值,也会触发事件  
36. }  
我们上面传递的第一个参数是监听者,这个方法也是在监听者中实现的,当属性值发生变化的时候,这个方法会被回调
这个方法的参数:
第一个参数:键值路径
第二个参数:监听对象
第三个参数:变化的值
第四个参数:传递的内容
我们看到代码中有一个特殊的参数:第三个参数:NSDirctionary类型的
其实我们如果不知道是干什么的,我们可以打印一下他的结果看一下,很简单,这里就不截图说明了
我们会发现他有两个键值对
key是:new和old
他们就是分别代表这个属性值变化的前后值,同时他们的得到也和之前我们添加监听对象时设置的第三个参数有关:
NSKeyValueObservingOptionNew |NSKeyValueObservingOptionOld
那个地方设置了几种状态,这里的NSDirctionary中就会有几个键值对

3、销毁方法
这个并不属于KVO的内容了,只是在这里用到了就顺便说一下
[objc]  view plaincopy
1. - (void)dealloc{  
2.       
3.     //移除观察者  
4.     [_children removeObserver:self forKeyPath:@"hapyValue"];  
5.     [_children removeObserver:self forKeyPath:@"hurryValue"];  
6.       
7. }  
我们在创建一个对象的时候会调用alloc方法,当对象被销毁的时候会调用dealloc这个方法,这个和C++中的析构函数一样,Java中有垃圾回收器,所以没有此类的方法,但是有一个finalize方法,其实这个方法就是在垃圾回收器回收对象的时候会调用,和这个功能差不多,但是在Java中,我们并不提倡使用这个方法。因为会造成GC的回收发生错误。
我们在销毁方法中需要移除监听者

总结
这一篇就介绍了OC中比较有特色的两个机制:KVC和KVO
KVC:就是可以暴力的去get/set类的私有属性,同时还有强大的键值路径对数组类型的属性进行操作
KVO:监听类中属性值变化的

转载于:https://www.cnblogs.com/GhostKZShadow/p/5105176.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/375210.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

8086加法指令ADD

加法指令ADD(ADDition) ADD OPRD1,OPRD2 ;OPRD1<--OPRD1OPRD2 ;完成OPRD1与OPRD2相加 ,结果保存在OPRD1中CODE SEGMENT MOV AX,1 MOV BX,2 ADD AX,BX ;AX<--AXBX ,结果AX3CODE ENDS参与运算的操作数类型必须保持一致,同为字节或字可组合以下几种形式&…

Fragment基础讲解

//新建一个碎片public class LeftFragment extends Fragment { Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // 加载一个碎片界面 View view inflater.inflate(R.layout.leftfragment, container, false)…

[bzoj1012](JSOI2008)最大数maxnumber(Fenwick Tree)

Description 现在请求你维护一个数列&#xff0c;要求提供以下两种操作&#xff1a; 1、 查询操作。语法&#xff1a;Q L 功能&#xff1a;查询当前数列中末尾L个数中的最大的数&#xff0c;并输出这个数的值。限制&#xff1a;L不超过当前数列的长度。 2、 插入操作。语法&…

javaScript转换日期合格式

javascript如何将时间日期转换为Date对象:有时候需要讲一个字符串型的时间日期转换为Date时间对象&#xff0c;下面就通过一个简单的实例提供一种解决方案&#xff0c;当然也是一种思路&#xff0c;可以进行一定的变通&#xff0c;以达到举一反三的效果。例如这里有一个时间日期…

8086减法指令SUB

减法指令SUB(SUBtraction) SUB OPRD1,OPRD2 ; OPRD1<-- OPRD1-OPRD2 都影响FLAG标志寄存器,同样的包含两种含义(有符号减法和无符号减法)

奇怪吸引子---Dadras

奇怪吸引子是混沌学的重要组成理论&#xff0c;用于演化过程的终极状态&#xff0c;具有如下特征&#xff1a;终极性、稳定性、吸引性。吸引子是一个数学概念&#xff0c;描写运动的收敛类型。它是指这样的一个集合&#xff0c;当时间趋于无穷大时&#xff0c;在任何一个有界集…

8086 INC, DEC

INC OPRD ;OPRD<--OPRD1 ;自加1指令code segmentmov ax,0inc ax ;ax<--ax1 ,ax1inc ax ;ax<--ax1 ,ax2code endsDEC OPRD ;OPRD<--OPRD-1 ;自减1指令code segmentmov ax,5dec ax ;ax<--ax-1 ,ax4 code ends

iPhone UITableViewCell如何滚动到视图顶端。

如何让UITableViewCell滚动到视图顶端。 - (void)scrollToRowAtIndexPath:(NSIndexPath *)indexPath atScrollPosition:(UITableViewScrollPosition)scrollPosition animated:(BOOL)animated;- (void)scrollToNearestSelectedRowAtScrollPosition:(UITableViewScrollPosition)s…

app 一些常用的

发短信 &#xff1a;sms:10086 打电话&#xff1a;tel:10086 1、-webkit-tap-highlight-color:rgba(255,255,255,0)可以同时屏蔽ios和android下点击元素时出现的阴影。备注&#xff1a;transparent的属性值在android下无效。 2、-webkit-appearance:none可以同时屏蔽输入框怪异…

8086乘法指令MUL,IMUL

对于加减指令来说CPU对有符号加减和无符号加减一视同仁,根据我们需要把它作为有符号的结果还是无符号的结果,但是乘除法指令区分有符号乘除和无符号乘除指令 无符号数乘法指令MUL(MULtiply) MUL OPRD(OPRD可以用除立即数以外的任何寻址方式)OPRD是八位一个乘数默认在AL中 则&am…

hdu 4857 逃生 拓扑排序

逃生题目连接&#xff1a; http://acm.hdu.edu.cn/showproblem.php?pid4857 Description 糟糕的事情发生啦&#xff0c;现在大家都忙着逃命。但是逃命的通道很窄&#xff0c;大家只能排成一行。 现在有n个人&#xff0c;从1标号到n。同时有一些奇怪的约束条件&#xff0c;每个…

指针数组,数组指针,指针函数,函数指针(转)

int *p[4]; //指针数组。 是个有4个元素的数组&#xff0c; 每个元素的是指向整型的指针。(数组的每个元素都是指针)int (*p)[4]; //数组指针。 它是一个指针&#xff0c;指向有4个整型元素的数组。 (一个指针指向有4个整型元素的数组)int *…

8086除法指令DIV,IDIV

无符号除法指令DIV(DIVision) DIV OPRD ;除数OPRD决定是8位除法还是16位除法;OPRD8位,则被除数默认在AX中,AX除以OPRD的商保存在AL中,余数保存在AH中;OPRD16位,则被除数默认在DX与AX中,结果的商保存在AX中,余数保存到DX中assume cs:code data segmentdb 2,4 data ends code se…

Hibernate 基础配置及常用功能(二)

本章主要是描述几种经典映射关系&#xff0c;顺带比较Hibernate4.x和Hibernate5.x之间的区别。 一、建立测试工程目录 有关实体类之间的相互映射关系&#xff0c;Hibernate官方文档其实描述的非常详细&#xff0c;这里只提供几种常见映射。&#xff08;推荐4.3.11版本的 hibern…

三言两语

人生中总是在选择。每当做一件事我们都应该问问我们的内心&#xff0c;或多或少我们都能理解一点人生的真谛。 最近时间很充裕&#xff0c;也就想了好多事情。首先我想明白的第一件事就是做任何事就要勇敢的去面对、去追求。喜欢一个女孩子大概有8年了吧&#xff01;这期间我们…

8086逻辑移位指令SHL和SHR

SHL逻辑左移指令 SHL OPRD M;把操作数OPRD左移M位,M为位移次数,为1或为CL(位移超过1次用CL表示) ;每移动一位右边用0补足一位,移出的最高位进入CF(最后移出的一位写入CF) MOV AL,00010011B ;13H 00010011B SHL AL,1 ;把AL左移1位,移出的最高位0进入CF,右边0补足1位…

YTU 2903: A--A Repeating Characters

2903: A--A Repeating Characters 时间限制: 1 Sec 内存限制: 128 MB提交: 50 解决: 30题目描述 For this problem,you will write a program that takes a string of characters,S,and creates a new string of characters,T,with each character repeated R times.That is,…

JavaScript 模拟装饰者模式

/*** 抽象coffee父类&#xff0c;其实可以不用的*/ function Coffee () {} Coffee.prototype.cost function() {throw 实现这个方法; }; /*** 黑咖啡&#xff0c;其实可以不用继承的&#xff1b;*/ function BlackCoffee () {} // BlackCoffee.prototype new Coffee(); // Bl…

8086算术移位指令SAL和SAR

SAL算术左移指令同逻辑左移指令进行相同动作,机器指令一样,只是为了方便记忆而提供的两个助记符 SAR算术右移指令 SAR OPRD,M ;该指令使操作数右移M位,每移动1位左边的符号保持不变,移出的最低位进入CF mov al,26H ;00100110B 右移1位 00010011B sar al,1 ;26H/2H13H mov a…

const 和readonly

原文:http://www.cnblogs.com/royenhome/archive/2010/05/22/1741592.html 关于 const和readonly修饰符之间的区别,要牵涉到C#中两种不同的常量类型: 静态常量(compile-time constants) 和动态常量(runtime constants) 静态常量是指编译器在编译时候会对常量进行解析,并将常量的…