A brief analysis of KVO examples
I have encountered a problem recently. When dealing with a comment interface in the project, because I directly use UIWebView to display the comment list, there was a messy advertisement with CGSize (320, 65) on the page I received, which was very annoying. Some advertisements are very convenient to paste their own logo on the head coordinates, but at the end, because the length of comments on each page is different, the coordinates are also different, so you cannot give the dead coordinates to paste the logo. , This problem is solved well through KVO.
@KVO Overview:
KVO, that is, Key-Value Observing, it provides a mechanism that when the attributes of the specified object are modified, the object will be notified.
Simply put, every time the attributes of the specified observed object are modified, KVO will automatically notify the corresponding observer.
The steps for use are as follows:
1. Register, specify the attributes of the observer,
2. Implement callback method
3. Trigger callback method
4. Remove observation
Code example: Copy the code as follows:
-(void)viewDidLoad{
// KVO, as an observer, as long as the property "contentSize" changes, the callback method will notify
[_webView.scrollView addObserver:self forKeyPath:@"contentSize" options:NSKeyValueObservingOptionNew context:NULL];
}
// Callback method
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(voidvoid *)context
{{
if(object == _webView.scrollView && [keyPath isEqualToString:@"contentSize"])
{{
// Get the maximum Y coordinate
CGSize size = _webView.scrollView.contentSize;
if (size.height > 568.0) {
// Block ads
_hideBottomImage = [[UIImageView alloc] initWithFrame:CGRectMake(0, size.height-67, ScreenWidth, 67)];
_hideBottomImage.image = [UIImage imageNamed:@"banner"];
[_webView.scrollView addSubview:_hideBottomImage];
[_hideBottomImag release];
}
}
else
{{
// Call the parent class method
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
}
}
- (void)dealloc{//--->You can also call the dealloc method in the ARC environment, but you don't need to write [super dealloc]
// Remove KVO, otherwise it will cause resource leakage
[_webView.scrollView removeObserver:self forKeyPath:@"contentSize"];
[super dealloc];
}
The above is for the contentSize property, and other properties are similar.
KVC
Usually, we all assign and get values through the set and get methods of attributes. Here we introduce the use of Key-Value-Coding (KVC) key-value encoding to assign and get values to the attributes of a class.
1. Basic method (setValue:forKey: valueForKey)
Copy code code as follows:
// ---Define a Student class (there is no operation on the .m file)
#import <Foundation/Foundation.h>
@class HMTClass;
@interface HMTStudent : NSObject{
NSString * _name;
BOOL _test;
BOOL _isTest;
BOOL test;
BOOL isTest;
}
@property (nonatomic,copy)NSString * name;
@property (nonatomic,copy)NSString * sex;
@property (nonatomic,assign)NSInteger age;
@property (nonatomic,strong) HMTClass * hmtClass;
@end
// ---main file
HMTStudent * student = [[HMTStudent alloc] init];
student.hmtClass = [[HMTClass alloc] init];
student.name = @"humingtao"; // set method assignment
// KVC assignment
[student setValue:@"mawei is dog" forKey:@"name"];
[student setValue:@"m" forKey:@"sex"];
[student setValue:@(10) forKey:@"age"];
// Get the value
NSLog(@"%s__%d__|%@",__FUNCTION__,__LINE__,[student valueForKey:@"name"]);
Special attention:
I also defined 4 BOOL value variables in the class to verify the order of KVC access attribute keys
[student setValue:@(YES) forKey:@"test"];
The result is: _test―>_isTest―>test―>isTest
2. Key path access (used to attribute setValue:ForKeyPath: forKeyPath)
Copy code code as follows:
// Create a class class
@interface HMTClass: NSObject
@property (nonatomic,copy)NSString * name;
@end
Then in the first point above, a class attribute hmtClass is written in the Student class.
Copy code code as follows:
HMTClass *hmtClass = [[HMTClass alloc]init];
[hmtClass setValue:@"Cosmic Class 1" forKey:@"name"];
[student setValue:hmtClass forKey:@"hmtClass"];
NSString *hmtClassName = [student valueForKeyPath:@"hmtClass.name"];
//You can save the value like this
[student setValue:@"Cosmic Class 1" forKeyPath:@"hmtClass.name"];
student.hmtClass.name = [student valueForKeyPath:@"hmtClass.name"];
3. Automatically encapsulate basic data types. We add the score attribute NSInteger number to the Student class;
Copy code code as follows:
#import <Foundation/Foundation.h>
@class HMTClass;
@interface HMTStudent : NSObject
{{
NSString *_name;
NSInteger number;
}
@end
[student setValue:@"100" forKeyPath:@"number"];
NSString *number = [student valueForKey:@"number"];
It can be seen that the attribute value set with NSString* type @"100", and our attribute is of NSInteger type, so there is no problem with access.
4. Add an array NSArray to the Student class to represent other students.
Copy code code as follows:
#import <Foundation/Foundation.h>
@class HMTClass;
@interface HMTStudent : NSObject
{{
NSArray *manyStudents;
}
@end
Student *student1 = [[HMTStudent alloc]init];
Student *student2 = [[HMTStudent alloc]init];
Student *student3 = [[HMTStudent alloc]init];
[student1 setValue:@"200" forKey:@"number"];
[student2 setValue:@"300" forKey:@"number"];
[student3 setValue:@"400" forKey:@"number"];
NSArray *array = [NSArray arrayWithObjects:student1,student2,student3,nil];
[student setValue:array forKey:@"manyStudents"];
NSLog(@"%@",[student valueForKeyPath:@"manyStudents.number"]);
Printed out is an array (200,300,400)