【IOS 开发学习总结-OC-30】★★OC之foundation 框架——集合(NSSet 与 NSMutableSet)
2015-10-04 09:20
831 查看
有关NSSet的概述介绍参见前面的一篇博文: 【IOS 开发学习总结-OC-28】★objective-c之foundation 框架——集合类的综述
它与 数组NSArray 最大的不同是:元素没有索引。除此之外,它们有大量相似之处,它们在如下方面的调用机制都很 相似。
1. 都可通过 count 方法获取集合元素的数量。
2. 都可通过快速枚举来遍历集合元素。
3. 都提供了集合的所有的元素和部分元素进行 KVO 编程的方法。
4. 都提供了
5. 通过 objectEnumerator方法获取NSEnumerator枚举器对集合元素进行遍历。对 NSSet 提供反向迭代器没有意义——NSSet 集合本身就是无序的。
6. 都提供了
NSSet常用的方法:
1.
2.
3.
4.
5.
说明:
6.
7.
8.
9.
10.
11.
12.
示例程序:
编译运行结果:
1. 2个对象通过 isEqual:方法比较返回 YES;
2. 2个对象的 hash 方法返回值也相等。
示例程序:
FKUser.h
FKUser.m
NSSetTest2.m
运行结果:
说明:
在 上面的代码中,如果没有重写Hash 方法的话,会输出:
上面的代码输出 NSSet 集合中只包含4个元素,,但输出来了
特别注意:
如果需要把一个对象放入 NSSet 集合中,如果重写该对象对应类的
如果2个 对象通过
对象中作为
类似于 NSMutableArray 与 NSArray的关系,NSMutableSet主要在 NSSet的基础上,增加了添加元素,删除元素的方法,并增加了对集合计算交集,并集,差集的方法。
1.
2.
3.
4.
5.
6.
7.
8.
示例程序:
NSMutableSetTest.m
编译运行结果:
当向NSCountedSet中添加元素时,如果没有这个元素,就添加进去,同时该元素的添加次数标注为1,再添加同一元素时,不会接纳该元素,但会使添加次数+1.当从NSCountedSet中删除元素时,只是将该元素的添加次数-1,只有该元素的添加次数变为0时,该元素才会真正从NSCountedSet集合中删除。
NSCountedSet提供的返回某个元素的添加次数的方法是:
示例代码:
NSCountedSetTest.m
编译运行结果:
NSMutableOrderedSet 是NSOrderedSet的拓展,增加了增,删,替换,集合排序,交集,并集,差集等功能。
NSOrderedSet 不允许元素重复——这与NSSet相同。可以保持元素的添加顺序,而且每个元素都有索引,可以根据索引操作元素。——这又与 NSArray 相似。
示例代码:
编译运行结果:
NSSet的功能和用法
NSSet按 Hash 算法 来存储集合中的元素,因此具有很好的存取 和查找性能。它与 数组NSArray 最大的不同是:元素没有索引。除此之外,它们有大量相似之处,它们在如下方面的调用机制都很 相似。
1. 都可通过 count 方法获取集合元素的数量。
2. 都可通过快速枚举来遍历集合元素。
3. 都提供了集合的所有的元素和部分元素进行 KVO 编程的方法。
4. 都提供了
valueForKey:和
setValue:forKey:方法对集合元素整体进行 KVC 编程 。
5. 通过 objectEnumerator方法获取NSEnumerator枚举器对集合元素进行遍历。对 NSSet 提供反向迭代器没有意义——NSSet 集合本身就是无序的。
6. 都提供了
makeObjectsPerformSelector:和
makeObjectsPerformSelector:withObject:方法对集合元素整体调用某个方法,以及
enumerateObjectsUsingBlock:和
enumerateObjectsWithOptions:usingBlock:对集合整体或部分元素迭代执行代码块。
NSSet的基本用法
NSSet同样提供了类方法和实例方法来初始化NSSet集合,其中,以 set 开头的为类方法,以 init 开头的方法为实例方法。NSSet常用的方法:
1.
setByAddingObject:向集合中添加一个新元素 ,返回添加元素后的新集合。
2.
setByAddingObjectsFromSet:使用NSSet集合向集合中添加多个元素,返回添加元素后的新集合。
3.
setByAddingObjectsFromArray:使用 NSArray 集合向集合添加多个新元素,返回添加元素后的新集合。
4.
allObjects:返回该集合中所有元素组成的 NSArray.
5.
anyObject:返回该集合中的某个元素。——该方法返回的元素是不确定的,但该方法并不保证随机返回集合元素。
说明:
6.
containsObject:判断集合是否包含指定元素
7.
member:判断该集合是否包含与 该参数相等的元素。——如果包含,返回相等的元素,否则返nil.
8.
objectsPassingTest:需要传入一个代码块对集合元素进行过滤,满足该代码块 条件的集合元素被保留下来并组成一个新的 NSSet 集合作为返回值。
9.
objectsWithOptions:PassingTest:与前一方法类似,只是额外地传入一个 NSEnumerationOptions 迭代选项参数。
10.
isSubsetOfSet:判断当前集合是否为另一个集合的子集。
11.
intersectsSet:判断2个集合的元素是否有 相同的元素。——是否有交集。
12.
isEqualSet:判断2个集合的元素是否相等。
示例程序:
#import <Foundation/Foundation.h> // 定义一个函数,该函数可把NSArray或NSSet集合转换为字符串 NSString* NSCollectionToString(id collection) { NSMutableString* result = [NSMutableString stringWithString:@"["]; // 使用快速枚举遍历NSSet集合 for(id obj in collection) { [result appendString:[obj description]]; [result appendString:@", "]; } // 获取字符串长度 NSUInteger len = [result length]; // 去掉字符串最后的两个字符 [result deleteCharactersInRange:NSMakeRange(len - 2, 2)]; [result appendString:@"]"]; return result; } int main(int argc , char * argv[]) { @autoreleasepool{ // 用4个元素初始化NSSet集合, // 故意传入两个相等的元素, NSSet集合只会保留一个元素 NSSet* set1 = [NSSet setWithObjects: @"疯狂iOS讲义" , @"疯狂Android讲义", @"疯狂Ajax讲义" ,@"疯狂iOS讲义" , nil]; // 程序输出set1集合中元素个数为3 NSLog(@"set1集合中元素个数为%ld" , [set1 count]); NSLog(@"s1集合:%@" , NSCollectionToString(set1)); NSSet* set2 = [NSSet setWithObjects: @"孙悟空" , @"疯狂Android讲义", @"猪八戒" , nil]; NSLog(@"s2集合:%@" , NSCollectionToString(set2)); // 向set1集合中添加单个元素,将添加元素后生成的新集合赋给set1 set1 = [set1 setByAddingObject:@"Struts 2.1权威指南"]; NSLog(@"添加一个元素后:%@" , NSCollectionToString(set1)); // 使用NSSet集合向set1集合中添加多个元素,相当计算两个集合的并集 NSSet* s = [set1 setByAddingObjectsFromSet:set2]; NSLog(@"set1与set2的并集:%@" , NSCollectionToString(s)); // 计算两个NSSet集合的是否有交集 BOOL b = [set1 intersectsSet:set2]; NSLog(@"set1与set2是否有交集:%d" , b);// 将输出代表YES的1 // 判断set2是否是set1的子集 BOOL bo = [set2 isSubsetOfSet:set1]; NSLog(@"set2是否为set1的子集:%d" , bo);// 将输出代表NO的0 // 判断NSSet集合是否包含指定元素 BOOL bb = [set1 containsObject:@"疯狂Ajax讲义"]; NSLog(@"set1是否包含\"疯狂Ajax讲义\":%d" , bb);// 将输出代表YES的1 // 下面两行代码将取出相同的元素,但取出哪个元素是不确定的。 NSLog(@"set1取出一个元素:%@" , [set1 anyObject]); NSLog(@"set1取出一个元素:%@" , [set1 anyObject]); // 使用代码块对集合元素进行过滤 NSSet* filteredSet = [set1 objectsPassingTest: ^(id obj, BOOL *stop) { return (BOOL)([obj length] > 8); }]; NSLog(@"set1中元素的长度大于8的集合元素有:%@" , NSCollectionToString(filteredSet)); } }
编译运行结果:
2015-10-03 19:44:53.100 923[2729:148826] set1集合中元素个数为3 2015-10-03 19:44:53.103 923[2729:148826] s1集合:[疯狂Android讲义, 疯狂iOS讲义, 疯狂Ajax讲义] 2015-10-03 19:44:53.104 923[2729:148826] s2集合:[孙悟空, 疯狂Android讲义, 猪八戒] 2015-10-03 19:44:53.104 923[2729:148826] 添加一个元素后:[疯狂Android讲义, 疯狂iOS讲义, Struts 2.1权威指南, 疯狂Ajax讲义] 2015-10-03 19:44:53.104 923[2729:148826] set1与set2的并集:[疯狂iOS讲义, 猪八戒, 疯狂Ajax讲义, 疯狂Android讲义, 孙悟空, Struts 2.1权威指南] 2015-10-03 19:44:53.105 923[2729:148826] set1与set2是否有交集:1 2015-10-03 19:44:53.105 923[2729:148826] set2是否为set1的子集:0 2015-10-03 19:44:53.105 923[2729:148826] set1是否包含"疯狂Ajax讲义":1 2015-10-03 19:44:53.106 923[2729:148826] set1取出一个元素:疯狂Android讲义 2015-10-03 19:44:53.106 923[2729:148826] set1取出一个元素:疯狂Android讲义 2015-10-03 19:44:53.107 923[2729:148826] set1中元素的长度大于8的集合元素有:[疯狂Android讲义, Struts 2.1权威指南]
NSSet 判断集合元素重复的标准
HahSet集合判断2个元素相等的标准:1. 2个对象通过 isEqual:方法比较返回 YES;
2. 2个对象的 hash 方法返回值也相等。
示例程序:
FKUser.h
#import <Foundation/Foundation.h> @interface FKUser : NSObject @property (nonatomic , copy) NSString* name; @property (nonatomic , copy) NSString* pass; - (id) initWithName:(NSString*) aName pass:(NSString*) aPass; - (void) say:(NSString*) content; @end
FKUser.m
#import "FKUser.h" @implementation FKUser @synthesize name; @synthesize pass; - (id) initWithName:(NSString*) aName pass:(NSString*) aPass { if(self = [super init]) { name = aName; pass = aPass; } return self; } - (void) say:(NSString*) content { NSLog(@"%@说:%@",self.name , content); } // 会重写isEqual:方法,重写该方法的比较标准是, // 如果两个FKUser的name、pass相等,即可认为两个FKUser相等。 - (BOOL) isEqual:(id)other { if(self == other) { return YES; } if([other class] == FKUser.class) { FKUser* target = (FKUser*)other; return [self.name isEqualToString:target.name] && [self.pass isEqualToString:target.pass]; } return NO; } // 重写hash方法,重写该方法的比较标准是, // 如果两个FKUser的name、pass相等,两个FKUser的hash方法返回值相等 - (NSUInteger) hash { NSLog(@"===hash==="); NSUInteger nameHash = name == nil ? 0 : [name hash]; NSUInteger passHash = pass == nil ? 0 : [pass hash]; return nameHash * 31 + passHash; } // 重写description方法,可以直接看到FKUser对象的状态 - (NSString*) description { return [NSString stringWithFormat: @"<FKUser[name=%@, pass=%@]>" , self.name , self.pass]; } @end
NSSetTest2.m
#import <Foundation/Foundation.h> #import "FKUser.h" // 定义一个函数,该函数可把NSArray或NSSet集合转换为字符串 NSString* NSCollectionToString(id array) { NSMutableString* result = [NSMutableString stringWithString:@"["]; for(id obj in array) { [result appendString:[obj description]]; [result appendString:@", "]; } // 获取字符串长度 NSUInteger len = [result length]; // 去掉字符串最后的两个字符 [result deleteCharactersInRange:NSMakeRange(len - 2, 2)]; [result appendString:@"]"]; return result; } int main(int argc , char * argv[]) { @autoreleasepool{ NSSet* set = [NSSet setWithObjects: [[FKUser alloc] initWithName:@"sun" pass:@"123"], [[FKUser alloc] initWithName:@"bai" pass:@"345"], [[FKUser alloc] initWithName:@"sun" pass:@"123"], [[FKUser alloc] initWithName:@"tang" pass:@"178"], [[FKUser alloc] initWithName:@"niu" pass:@"155"], nil]; NSLog(@"set集合元素的个数:%ld" , [set count]); NSLog(@"%@" , NSCollectionToString(set)); } }
运行结果:
2015-10-03 20:28:38.599 923[2877:165034] ===hash=== 2015-10-03 20:28:38.600 923[2877:165034] ===hash=== 2015-10-03 20:28:38.601 923[2877:165034] ===hash=== 2015-10-03 20:28:38.601 923[2877:165034] ===hash=== 2015-10-03 20:28:38.602 923[2877:165034] ===hash=== 2015-10-03 20:28:38.602 923[2877:165034] set集合元素的个数:4 2015-10-03 20:28:38.603 923[2877:165034] [<FKUser[name=bai, pass=345]>, <FKUser[name=sun, pass=123]>, <FKUser[name=tang, pass=178]>, <FKUser[name=niu, pass=155]>]
说明:
在 上面的代码中,如果没有重写Hash 方法的话,会输出:
2015-10-03 20:37:02.556 923[2973:170275] set集合元素的个数:5 2015-10-03 20:37:02.558 923[2973:170275] [<FKUser[name=sun, pass=123]>, <FKUser[name=sun, pass=123]>, <FKUser[name=niu, pass=155]>, <FKUser[name=bai, pass=345]>, <FKUser[name=tang, pass=178]>]
上面的代码输出 NSSet 集合中只包含4个元素,,但输出来了
===hash===5次,说明 NSSet 集合每次添加一个集合 元素,总会调用该元素的 Hash 方法——所有的对象都有 hash 方法,——因为所有的对象都继承了 NSObject 类。
特别注意:
如果需要把一个对象放入 NSSet 集合中,如果重写该对象对应类的
isEqual:方法,也应该重写其 Hash 方法。——其规则是:如果2个 对象通过
isEqual:方法比较返回YES时,这2个对象的 Hash方法的返回值也应该相同。
Hash 方法
重写Hash 方法的基本原则:
程序 运行过程中,同一个 对象多次调用 Hash 应该返回想通过的值。如果2个 对象通过
isEqual:方法比较返回YES时,这2个对象的 Hash方法的返回值也应该相同。
对象中作为
isEqual:比较标准的实例变量,都应该用来计算hashCode值。
重写Hash 方法的步骤:
NSMutableSet 的功能与用法
由于NSMutableSet可以动态添加集合元素,因此,创建 NSSet 集合时可指定底层 Hash表的初始容量。类似于 NSMutableArray 与 NSArray的关系,NSMutableSet主要在 NSSet的基础上,增加了添加元素,删除元素的方法,并增加了对集合计算交集,并集,差集的方法。
1.
addObject:向集合中添加单个元素
2.
removeObject:从集合中删除单个元素
3.
removeAllObjects:从集合中删除所有元素
4.
addObjectsFromArray:使用数组作为参数,想 NSSet 集合中添加参数数组中的所有元素。
5.
unionSet:计算2个集合的并集。
6.
minusSet:计算2个集合的差集。
7.
intersectSet:计算2个集合的交集。
8.
setSet:用后一个集合的元素替换已有集合中所有的元素。
示例程序:
NSMutableSetTest.m
// Created by yeeku on 2013-4-22. // Copyright (c) 2013年 crazyit.org. All rights reserved. #import <Foundation/Foundation.h> // 定义一个函数,该函数可把NSArray或NSSet集合转换为字符串 NSString* NSCollectionToString(id collection) { NSMutableString* result = [NSMutableString stringWithString:@"["]; // 使用快速枚举遍历NSSet集合 for(id obj in collection) { [result appendString:[obj description]]; [result appendString:@", "]; } // 获取字符串长度 NSUInteger len = [result length]; // 去掉字符串最后的两个字符 [result deleteCharactersInRange:NSMakeRange(len - 2, 2)]; [result appendString:@"]"]; return result; } int main(int argc , char * argv[]) { @autoreleasepool{ // 创建一个初始容量为10的Set集合 NSMutableSet* set = [NSMutableSet setWithCapacity:10]; [set addObject:@"疯狂iOS讲义"]; NSLog(@"添加1个元素后:%@" , NSCollectionToString(set)); [set addObjectsFromArray: [NSArray arrayWithObjects:@"疯狂Android讲义" , @"疯狂Ajax讲义" , @"疯狂XML讲义" ,nil]]; NSLog(@"使用NSArray添加3个元素后:%@" , NSCollectionToString(set)); [set removeObject:@"疯狂XML讲义"]; NSLog(@"删除1个元素后:%@" , NSCollectionToString(set)); // 再次创建一个Set集合 NSSet* set2 = [NSSet setWithObjects: @"孙悟空", @"疯狂iOS讲义" , nil]; // 计算两个集合的并集,直接改变set集合的元素 [set unionSet: set2]; // 计算两个集合的差集,直接改变set集合的元素 // [set minusSet: set2]; // 计算两个集合的交集,直接改变set集合的元素 // [set intersectSet: set2]; // 用set2的集合元素替换set的集合元素,直接改变set集合的元素 // [set setSet: set2]; NSLog(@"%@" , NSCollectionToString(set)); } }
编译运行结果:
2015-10-04 08:46:05.754 923[1130:18827] 添加1个元素后:[疯狂iOS讲义] 2015-10-04 08:46:05.756 923[1130:18827] 使用NSArray添加3个元素后:[疯狂iOS讲义, 疯狂Ajax讲义, 疯狂Android讲义, 疯狂XML讲义] 2015-10-04 08:46:05.757 923[1130:18827] 删除1个元素后:[疯狂iOS讲义, 疯狂Ajax讲义, 疯狂Android讲义] 2015-10-04 08:46:05.759 923[1130:18827] [疯狂iOS讲义, 疯狂Ajax讲义, 疯狂Android讲义, 孙悟空]
NSCountedSet 的功能与用法
NSCountedSet是NSMutableSet的子类。NSCountedSet与普通NSMutableSet的不同的是:它为每个元素额外维护一个添加次数的状态。当向NSCountedSet中添加元素时,如果没有这个元素,就添加进去,同时该元素的添加次数标注为1,再添加同一元素时,不会接纳该元素,但会使添加次数+1.当从NSCountedSet中删除元素时,只是将该元素的添加次数-1,只有该元素的添加次数变为0时,该元素才会真正从NSCountedSet集合中删除。
NSCountedSet提供的返回某个元素的添加次数的方法是:
countForObject:——获取指定元素的添加次数
示例代码:
NSCountedSetTest.m
// Created by yeeku on 2013-4-22. // Copyright (c) 2013年 crazyit.org. All rights reserved. #import <Foundation/Foundation.h> // 定义一个函数,该函数可把NSArray或NSSet集合转换为字符串 NSString* NSCollectionToString(id collection) { NSMutableString* result = [NSMutableString stringWithString:@"["]; // 使用快速枚举遍历NSSet集合 for(id obj in collection) { [result appendString:[obj description]]; [result appendString:@", "]; } // 获取字符串长度 NSUInteger len = [result length]; // 去掉字符串最后的两个字符 [result deleteCharactersInRange:NSMakeRange(len - 2, 2)]; [result appendString:@"]"]; return result; } int main(int argc , char * argv[]) { @autoreleasepool{ NSCountedSet* set = [NSCountedSet setWithObjects: @"疯狂iOS讲义" , @"疯狂Android讲义", @"疯狂Ajax讲义" , nil]; [set addObject:@"疯狂iOS讲义"]; [set addObject:@"疯狂iOS讲义"]; // 输出集合元素 NSLog(@"%@" , NSCollectionToString(set)); // 获取指定元素的添加顺序 NSLog(@"\"疯狂iOS讲义\"的添加次数为:%ld" , [set countForObject:@"疯狂iOS讲义"]); // 删除元素 [set removeObject:@"疯狂iOS讲义"]; NSLog(@"删除\"疯狂iOS讲义\"1次后的结果:%@" , NSCollectionToString(set)); NSLog(@"删除\"疯狂iOS讲义\"1次后的添加次数为:%ld" , [set countForObject:@"疯狂iOS讲义"]); // 重复删除元素 [set removeObject:@"疯狂iOS讲义"]; [set removeObject:@"疯狂iOS讲义"]; NSLog(@"删除\"疯狂iOS讲义\"3次后的结果:%@" , NSCollectionToString(set)); } }
编译运行结果:
2015-10-04 08:59:16.780 923[1168:23315] [疯狂iOS讲义, 疯狂Android讲义, 疯狂Ajax讲义] 2015-10-04 08:59:16.782 923[1168:23315] "疯狂iOS讲义"的添加次数为:3 2015-10-04 08:59:16.782 923[1168:23315] 删除"疯狂iOS讲义"1次后的结果:[疯狂iOS讲义, 疯狂Android讲义, 疯狂Ajax讲义] 2015-10-04 08:59:16.783 923[1168:23315] 删除"疯狂iOS讲义"1次后的添加次数为:2 2015-10-04 08:59:16.783 923[1168:23315] 删除"疯狂iOS讲义"3次后的结果:[疯狂Android讲义, 疯狂Ajax讲义]
有序集合(NSOrderedSet 与 NSMutableOrderedSet)
先说明一下,NSOrderedSet 与 NSMutableOrderedSet(后者是前者的子类),这俩货是个奇葩的综合体。既具有 NSSet 集合的特征,也具有数组NSArray类似的 功能。NSMutableOrderedSet 是NSOrderedSet的拓展,增加了增,删,替换,集合排序,交集,并集,差集等功能。
NSOrderedSet 不允许元素重复——这与NSSet相同。可以保持元素的添加顺序,而且每个元素都有索引,可以根据索引操作元素。——这又与 NSArray 相似。
示例代码:
#import <Foundation/Foundation.h> // 定义一个函数,该函数可把NSArray或NSSet集合转换为字符串 NSString* NSCollectionToString(id collection) { NSMutableString* result = [NSMutableString stringWithString:@"["]; // 使用快速枚举遍历NSSet集合 for(id obj in collection) { [result appendString:[obj description]]; [result appendString:@", "]; } // 获取字符串长度 NSUInteger len = [result length]; // 去掉字符串最后的两个字符 [result deleteCharactersInRange:NSMakeRange(len - 2, 2)]; [result appendString:@"]"]; return result; } int main(int argc , char * argv[]) { @autoreleasepool{ // 创建NSOrderedSet集合,故意使用重复的元素 // 程序看到程序只会保留一个元素 NSOrderedSet* set = [NSOrderedSet orderedSetWithObjects: [NSNumber numberWithInt:40], [NSNumber numberWithInt:12], [NSNumber numberWithInt:-9], [NSNumber numberWithInt:28], [NSNumber numberWithInt:12], [NSNumber numberWithInt:17], nil]; NSLog(@"%@" , NSCollectionToString(set)); // 下面方法都是根据索引来操作集合元素 // 获取第一个元素 NSLog(@"set集合的第一个元素 :%@" , [set firstObject]); // 获取最后一个元素 NSLog(@"set集合的最后一个元素 :%@" , [set lastObject]); // 获取指定索引处的元素 NSLog(@"set集合中索引为2的元素 :%@" , [set objectAtIndex:2]); NSLog(@"28在set集合中的索引为:%ld" , [set indexOfObject:[NSNumber numberWithInt:28]]); // 对集合进行过滤,获取元素值大于20的集合元素的索引 NSIndexSet* indexSet = [set indexesOfObjectsPassingTest: ^(id obj, NSUInteger idx, BOOL *stop) { return (BOOL)([obj intValue] > 20); }]; NSLog(@"set集合中元素值大于20的元素的索引为:%@" , indexSet); } }
编译运行结果:
2015-10-04 09:10:50.426 923[1213:27659] [40, 12, -9, 28, 17] 2015-10-04 09:10:50.427 923[1213:27659] set集合的第一个元素 :40 2015-10-04 09:10:50.427 923[1213:27659] set集合的第一个元素 :17 2015-10-04 09:10:50.428 923[1213:27659] set集合中索引为2的元素 :-9 2015-10-04 09:10:50.428 923[1213:27659] 28在set集合中的索引为:3 2015-10-04 09:10:50.429 923[1213:27659] set集合中元素值大于20的元素的索引为:<NSIndexSet: 0x7fdb3840c310>[number of indexes: 2 (in 2 ranges), indexes: (0 3)]
相关文章推荐
- 峰回路转,Firefox 浏览器即将重返 iOS 平台
- 峰回路转,Firefox 浏览器即将重返 iOS 平台
- 不可修补的 iOS 漏洞可能导致 iPhone 4s 到 iPhone X 永久越狱
- iOS 12.4 系统遭黑客破解,漏洞危及数百万用户
- 如何成为一名专家级的开发人员
- 每日安全资讯:NSO,一家专业入侵 iPhone 的神秘公司
- [转][源代码]Comex公布JailbreakMe 3.0源代码
- Ruby中的集合编写指南
- 插件管理框架 for Delphi(一)
- AVG 7.5.1.43 版本 序列号 集合
- SQL Server游标的使用/关闭/释放/优化小结
- 编写高质量代码改善C#程序――使用泛型集合代替非泛型集合(建议20)
- 使用CSS框架布局的缺点和优点小结
- C#检查指定对象是否存在于ArrayList集合中的方法
- 列举PHP的Yii 2框架的开发优势
- C#写入对象或集合类型数据到xml文件的方法
- C#中的集合用法分析
- .NET微信公众号开发之公众号消息处理
- Windows窗体的.Net框架绘图技术实现方法