统计代码行数
用终端到程序目录下输入下面的命令:
find ./ -name "*.m" -exec cat {} \; |wc -l
find ./ -name "*.h" -exec cat {} \; | wc -l
两个数相加就是
用终端到程序目录下输入下面的命令:
find ./ -name "*.m" -exec cat {} \; |wc -l
find ./ -name "*.h" -exec cat {} \; | wc -l
两个数相加就是
原文:http://www.drobnik.com/touch/2010/03/filtering-fun-with-predicates/
Being present longer than iPhone OS exists on the Mac platform NSPredicate was only introduced to us iPhone developers in Version 3.0 of the SDK. They have multiple interesting uses, some of which I am going to explore in this article.
You will see how you can filter an array of dictionaries, learn that the same also works for your own custom classes. Then we’ll see how to replace convoluted IF trees with simple predicates. We’ll explore how to use predicates to filter entries of a table view and finally peek into the inner workings of predicates.
Being simple and powerful at the same time it took me 3 hours to write this article. I hope you don’t give up halfway through it, because I promise it will be a great addition to your skillset as iPhone developer.
One interesting use of predicates is to filter an array for entries where a specific key matches some criteria. In the following example I am adding four people to an array in the form of individual dictionaries. Then I’m filtering for all the entries that contain the letter o in lastName.
NSMutableArray *people = [NSMutableArray array];[people addObject:[NSDictionary dictionaryWithObjectsAndKeys: @"Oliver", @"firstName", @"Drobnik", @"lastName", nil]];[people addObject:[NSDictionary dictionaryWithObjectsAndKeys: @"Steve", @"firstName", @"Jobs", @"lastName", nil]];[people addObject:[NSDictionary dictionaryWithObjectsAndKeys: @"Bill", @"firstName", @"Gates", @"lastName", nil]];[people addObject:[NSDictionary dictionaryWithObjectsAndKeys: @"Obiwan", @"firstName", @"Kenobi", @"lastName", nil]];NSPredicate *predicate = [NSPredicate predicateWithFormat:@"lastName CONTAINS[cd] %@",@"o"];NSArray *filteredArray = [people filteredArrayUsingPredicate:predicate];NSLog(@"%@", filteredArray); |
Note that the [cd] next to the operator like causes it to ignore case and diacritics. Case is obvious, o = O. Diacritics are “ancillary glyphs added to a letter”, e.g. ó which is adding an accent to a plain o. With the [d] option o == ò == ö.
In the sample I am creating a new filtered array, but NSMutableArray also has a method to do it in-place. filterUsingPredicate leaves only matching items in the array.
A variety of operators is possible when dealing with string properties:
Predicates can be very useful to avoid monstrous IF trees. You can chain multiple predicates with the logical operators AND, OR and NOT. To evaluate an expression on a specific object use the predicate’s evaluateWithObject method.
NSDictionary *person = [NSDictionary dictionaryWithObjectsAndKeys: @"Steve", @"firstName", @"Jobs", @"lastName", nil];NSPredicate *predicate = [NSPredicate predicateWithFormat: @"firstName ENDSWITH %@ AND lastName BEGINSWITH[c] %@", @"eve", @"j"];if ([predicate evaluateWithObject:person]){NSLog(@"Is YES, matches");} |
Now in the above samples we’ve only been using NSDictionary to old our firstName and lastName properties. A quick experiment shows us if this is also working for our own custom classes. Let’s create a Person class for this purpose. This only has our two properties plus an overriding description to output useful information and a class method to quickly create a Person instance.
Person.h
@interface Person : NSObject {NSString *firstName;NSString *lastName;}@property (nonatomic, retain) NSString *firstName;@property (nonatomic, retain) NSString *lastName;+ (Person *)personWithFirstName:(NSString *)firstName lastName:(NSString *)lastName;@end |
Person.m
#import "Person.h"@implementation Person@synthesize firstName, lastName;+ (Person *)personWithFirstName:(NSString *)firstName lastName:(NSString *)lastName{Person *person = [[[Person alloc] init] autorelease];person.firstName = firstName;person.lastName = lastName;return person;}- (NSString *)description{return [NSString stringWithFormat:@"<%@ '%@ %@'>",NSStringFromClass([self class]),firstName,lastName];}- (void) dealloc{[firstName release];[lastName release];[super dealloc];}@end |
Now let’s see if we still get the same result if we do the same filtering of an array, this time with our own Person instances in it.
Person *person1 = [Person personWithFirstName:@"Oliver" lastName:@"Drobnik"];Person *person2 = [Person personWithFirstName:@"Steve" lastName:@"Jobs"];Person *person3 = [Person personWithFirstName:@"Bill" lastName:@"Gates"];Person *person4 = [Person personWithFirstName:@"Obiwan" lastName:@"Kenobi"];NSArray *people = [NSArray arrayWithObjects:person1, person2, person3, person4, nil];NSPredicate *predicate = [NSPredicate predicateWithFormat:@"firstName CONTAINS[cd] %@",@"i"];NSArray *filteredArray = [people filteredArrayUsingPredicate:predicate];NSLog(@"%@", filteredArray); |
Yup! Still works! Now is that cool or what? One obvious use for predicates is to filter the data array in a table view controller to only match the contents of your search box.
To try this out we need to do the following:
RootViewController.h
#import <UIKit/UIKit.h>@interface RootViewController : UITableViewController <UISearchDisplayDelegate, UISearchBarDelegate>{NSArray *people;NSArray *filteredPeople;UISearchDisplayController *searchDisplayController;}@property (nonatomic, retain) NSArray *people;@property (nonatomic, retain) NSArray *filteredPeople;@property (nonatomic, retain) UISearchDisplayController *searchDisplayController;@end |
RootViewController.m
#import "RootViewController.h"#import "Person.h"@implementation RootViewController@synthesize people, filteredPeople;@synthesize searchDisplayController;- (void)dealloc{[searchDisplayController release];[people release];[filteredPeople release]; [super dealloc];}- (void)viewDidLoad{ [super viewDidLoad];self.title = @"Search People";Person *person1 = [Person personWithFirstName:@"Oliver" lastName:@"Drobnik"];Person *person2 = [Person personWithFirstName:@"Steve" lastName:@"Jobs"];Person *person3 = [Person personWithFirstName:@"Bill" lastName:@"Gates"];Person *person4 = [Person personWithFirstName:@"Obiwan" lastName:@"Kenobi"];people = [[NSArray alloc] initWithObjects:person1, person2, person3, person4, nil];// programmatically set up search barUISearchBar *mySearchBar = [[UISearchBar alloc] init];[mySearchBar setScopeButtonTitles:[NSArray arrayWithObjects:@"First",@"Last",nil]];mySearchBar.delegate = self;[mySearchBar setAutocapitalizationType:UITextAutocapitalizationTypeNone];[mySearchBar sizeToFit];self.tableView.tableHeaderView = mySearchBar;// programmatically set up search display controllersearchDisplayController = [[UISearchDisplayController alloc] initWithSearchBar:mySearchBar contentsController:self];[self setSearchDisplayController:searchDisplayController];[searchDisplayController setDelegate:self];[searchDisplayController setSearchResultsDataSource:self];[mySearchBar release];}#pragma mark Table view methods- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{if (tableView == self.searchDisplayController.searchResultsTableView){ return [self.filteredPeople count]; }else{ return [self.people count]; }}- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ static NSString *CellIdentifier = @"Cell"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; if (cell == nil) { cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease]; }Person *person;if (tableView == self.searchDisplayController.searchResultsTableView){ person = [self.filteredPeople objectAtIndex:indexPath.row]; }else{ person = [self.people objectAtIndex:indexPath.row]; }cell.textLabel.text = [NSString stringWithFormat:@"%@ %@", person.firstName, person.lastName]; return cell;}#pragma mark Content Filtering- (void)filterContentForSearchText:(NSString *)searchText scope:(NSString *)scope{NSPredicate *predicate;if ([scope isEqualToString:@"First"]){predicate = [NSPredicate predicateWithFormat: @"firstName CONTAINS[cd] %@", searchText];}else{predicate = [NSPredicate predicateWithFormat: @"lastName CONTAINS[cd] %@", searchText];}self.filteredPeople = [people filteredArrayUsingPredicate:predicate];}#pragma mark UISearchDisplayController Delegate Methods- (BOOL)searchDisplayController:(UISearchDisplayController *)controllershouldReloadTableForSearchString:(NSString *)searchString{ [self filterContentForSearchText:searchString scope: [[self.searchDisplayController.searchBar scopeButtonTitles] objectAtIndex:[self.searchDisplayController.searchBar selectedScopeButtonIndex]]]; // Return YES to cause the search result table view to be reloaded. return YES;}- (BOOL)searchDisplayController:(UISearchDisplayController *)controllershouldReloadTableForSearchScope:(NSInteger)searchOption{ [self filterContentForSearchText:[self.searchDisplayController.searchBar text] scope: [[self.searchDisplayController.searchBar scopeButtonTitles] objectAtIndex:searchOption]]; // Return YES to cause the search result table view to be reloaded. return YES;}@end |
Adding the search display controller is responsible for most of the additional code in this example. Just getting the filtered people to match our search has become very simple due to NSPredicate as you can see in the filterContentForSearchText method. The two UISearchDisplayController Delegate methods are called whenever you type something in the search box or switch between the scope buttons. In this case I am showing how to switch between searching in first names and last names.
The table view for the search results is actually dynamically created when needed. As it’s using the same data source and delegate methods as the original table view we need to respond differently based on which table view the methods are being called for. This is the reason for the IF in each of these methods. If we are in the search results we take the filteredPeople array, otherwise we use the original people array.
NSPredicate was only introduced into the iPhone SDKs as of version 3.0, so my guess is that there might a few instances in your code where you could simplify the logic with replacing a big IF tree with a simple predicate. Down the road, they are the only method how you can filter data coming from a fetch in CoreData.
In this article I’ve only used the predicteWithFormat method to create them. That’s actually a tremendous shortcut, because internally predicates are themselves consisting of several parts, mostly NSExpression instances. So if you feel that your code has become way too easy to understand by using predicates you can also replace them with the original composition.
Using expressions the general approach is to define a left hand expression and a right hand expression and put these into an NSComparisonPredicate. I’m just showing this here so that you can appreciate the simplicity of the shortcut method presented earlier.
NSExpression *lhs = [NSExpression expressionForKeyPath:@"firstName"];NSExpression *rhs = [NSExpression expressionForConstantValue:@"i"];NSPredicate *predicate = [NSComparisonPredicate predicateWithLeftExpression:lhs rightExpression:rhs modifier:NSDirectPredicateModifier type:NSContainsPredicateOperatorType options:NSCaseInsensitivePredicateOption | NSDiacriticInsensitivePredicateOption];// same as://NSPredicate *predicate = [NSPredicate predicateWithFormat:@"firstName CONTAINS[cd] %@", @"i"]; |
Component predicates are achieved the long way in a similar fashion by using NSCompoundPredicate, but there is no using going into these dark depths when the shortcut is so much more convenient.
Finally another hint without going into details: Predicate Templates. You can define any predicate with $Variables instead of an expression. Then when you need them you can use [template predicateWithSubstitutionVariables:] with a dictionary of values to substitute for the $Variables to prep a predicate ready for use.
iphoen do not have NSXML* librarys, wo can instead with touchxml,TouchXML is a lightweight replacement for Cocoa’s NSXMLcluster of classes. It is based on the commonly available Open Source libxml2 library.
you can dowload TouchXML library from TouchCode
find the guid here TouchXMLHowTo
import touchxml.h
#import “TouchXML.h”
use CXMLDocument to parse xml
// grabRSSFeed function that takes a string (blogAddress) as a parameter and
// fills the global blogEntries with the entries
-(void) grabRSSFeed:(NSString *)blogAddress {
// Initialize the blogEntries MutableArray that we declared in the header
blogEntries = [[NSMutableArray alloc] init];
// Convert the supplied URL string into a usable URL object
NSURL *url = [NSURL URLWithString: blogAddress];
// Create a new rssParser object based on the TouchXML “CXMLDocument” class, this is the
// object that actually grabs and processes the RSS data
CXMLDocument *rssParser = [[[CXMLDocument alloc] initWithContentsOfURL:url options:0 error:nil] autorelease];
// Create a new Array object to be used with the looping of the results from the rssParser
NSArray *resultNodes = NULL;
// Set the resultNodes Array to contain an object for every instance of an node in our RSS feed
resultNodes = [rssParser nodesForXPath:@"//item" error:nil];
// Loop through the resultNodes to access each items actual data
for (CXMLElement *resultElement in resultNodes) {
// Create a temporary MutableDictionary to store the items fields in, which will eventually end up in blogEntries
NSMutableDictionary *blogItem = [[NSMutableDictionary alloc] init];
// Create a counter variable as type “int”
int counter;
// Loop through the children of the current node
for(counter = 0; counter < [resultElement childCount]; counter++) {
// Add each field to the blogItem Dictionary with the node name as key and node value as the value
[blogItem setObject:[[resultElement childAtIndex:counter] stringValue] forKey:[[resultElement childAtIndex:counter] name]];
}
// Add the blogItem to the global blogEntries Array so that the view can access it.
[blogEntries addObject:[blogItem copy]];
}
}
CXMLDocument
| 员工绩效考核规定
作者:不详 来源于:转载 , 发布时间:2004-12-17 |
| 员工绩效考核规定
第一章 总则 第二章 绩效考核的分类: 第七条 年度绩效考核是行政人事部根据被考核者在本年度内的奖惩记录情况给予评价,并统计、汇总各季度绩效考核的得分后,得出的被考核者本年度绩效考核的最终得分。
第八条 每个项目所包括的考核因素如下: 第四章 年度绩效考核的内容和实施 第五章 附则 附:1、员工季度绩效考核程度图 表4—1 |
最佳开源PHP在线代理程序Glype Glype proxy script is a free-to-use, web-based proxy script written in PHP. Similar to a typical proxy server, a web-proxy script downloads requested web pages and files and forwards them back to the user. The service is provided by a web page itself, which allows instant access to the proxy without editing your browser connection settings. Web proxies are commonly used for anonymous browsing and bypassing censorship restrictions. There is a huge market for these sites and glype proxy allows webmasters to quickly and easily set up their own proxy sites.
NSString *content = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
int len = [content length];
// Auto released string
NSString * reversedStr = [[NSMutableString alloc] init];
// Probably woefully inefficient...
while (len > 0)
[reversedStr appendString:
[NSString stringWithFormat:@"%C", [content characterAtIndex:--len]]];
NSLog(reversedStr);
| 图1-1 iPhone开发中心首页 |
| 图1-2 下载iPhone SDK |
| 图1-3 iPhone开发工具图标 |
| 图1-4 拖放Xcode到Dock上 |