Runtime 、 Block
2015-12-15 19:53
309 查看
1 使用Block方式,对学生对象进行排序。
1.1 问题
在iOS4.0+ 和Mac OS X 10.6+ 中添加了Block概念,以对C语言进行扩展。在Block中可以定义参数列表、返回类型,还可以获取被定义在的作用域内的局部变量的值,并且能修改使用__block修饰的局部变量的值。Block本质上是一个变量,该变量中存储的数据是一段函数体。
1.2 方案
本案例要求定义一个学生类TRSTudent,然后创建该类的三个对象。用这三个对象建立一个数组,使用Block变量对这个数组排序。并将排序结果输出到控制台上。1.3 步骤
实现此案例需要按照如下步骤进行。步骤一:定义类TRStudent
首先,在Day05工程中新添加TRStudent.h文件,用于定义新的类TRStudent。
代码如下所示:
#import <Foundation/Foundation.h>
@interface TRStudent : NSObject
@property(nonatomic,assign)int age;
@property(nonatomic,copy)NSString* name;
@end
在上述代码中,以下代码:
@property(nonatomic,assign)int age;
在TRStudent类中定义了一个是整型属性age,用于存储学生的年龄。它有两个参数,一个是nonatomic,它代表对属性赋值的时候不加锁,即在多线程环境下访问时可能会出现数据错误,如果需要在多线程环境下运行,为保证数据不会出现错误,可使用atomic参数,它会在对属性赋值的时候加锁。另一个参数是assign,对于C语言的基本数据类型,只能选取这个参数。
在上述代码中,以下代码:
@property(nonatomic,copy)NSString* name;
在TRStudent类中定义了一个是NSString类的对象name,用于存储学生的姓名。它有两个参数,一个是nonatomic,另一个参数是copy,该参数一般用于NSObject类及其子类的对象,这些对象在赋值时实现深拷贝,即属性name指向的对象是赋值给它的对象的副本。
然后,在类TRStudent的实现部分,即在TRStudent.m文件中,重写description方法的实现,该方法用于在NSLog中用%@输出TRStudent类的对象值。
代码如下所示:
#import "TRStudent.h"
@implementation TRStudent
-(NSString *)description{
return [NSString stringWithFormat:@"name:%@ age:%d",self.name, self.age];
}
@end
步骤二:在主程序中创建三个学生对象
代码如下所示:
#import <Foundation/Foundation.h>
#import "TRStudent.h"
int main(int argc, const char * argv[])
{
@autoreleasepool {
// insert code here...
TRStudent* stu1 = [[TRStudent alloc]init];
stu1.age = 18;
stu1.name = @"zhangsan";
TRStudent* stu2 = [[TRStudent alloc]init];
stu2.age = 19;
stu2.name = @"lisi";
TRStudent* stu3 = [[TRStudent alloc]init];
stu3.age = 20;
stu3.name = @"wangwu";
}
return 0;
}
步骤三:在主程序中创建排序Block
代码如下所示:
#import <Foundation/Foundation.h>
#import "TRStudent.h"
int main(int argc, const char * argv[])
{
@autoreleasepool {
// insert code here...
TRStudent* stu1 = [[TRStudent alloc]init];
stu1.age = 18;
stu1.name = @"zhangsan";
TRStudent* stu2 = [[TRStudent alloc]init];
stu2.age = 19;
stu2.name = @"lisi";
TRStudent* stu3 = [[TRStudent alloc]init];
stu3.age = 20;
stu3.name = @"wangwu";
NSComparisonResult(^compare)(id stu1,id stu2);
compare = ^(id stu1,id stu2)
{
//类型转换
NSString* s1 = nil;
if([stu1 isMemberOfClass:[TRStudent class]])
{
s1 = ((TRStudent*)stu1).name;
}
NSString* s2 = nil;
if([stu2 isMemberOfClass:[TRStudent class]])
{
s2 = ((TRStudent*)stu2).name;
}
return [s1 compare:s2];
};
}
return 0;
}
上述代码中,以下代码:
NSComparisonResult(^compare)(id stu1,id stu2);
声明了Block变量compare,其中NSComparisonResult为Block的返回值类型。^为Block类型说明符,就像定义指针时使用*号一样。(id stu1,id stu2)为Block的形式参数。
Block本质上是变量,但因为其存储的数据是一段代码,所以它有返回值类型和形式参数。
上述代码中,以下代码:
compare = ^(id stu1,id stu2)
{
//类型转换
NSString* s1 = nil;
if([stu1 isMemberOfClass:[TRStudent class]])
{
s1 = ((TRStudent*)stu1).name;
}
NSString* s2 = nil;
if([stu2 isMemberOfClass:[TRStudent class]])
{
s2 = ((TRStudent*)stu2).name;
}
return [s1 compare:s2];
};
是实现了Block。以下语句:
compare = ^(id stu1,id stu2)
是对Block变量compare的赋值,将一段代码赋值给这个变量。在这段代码中,以下代码:
NSString* s1 = nil;
if([stu1 isMemberOfClass:[TRStudent class]])
{
s1 = ((TRStudent*)stu1).name;
}
是对形参stu1的类型检查,如果stu1是TRStudent类的对象,则将stu1中的name属性值赋值给s1。
步骤四:在主程序中对创建的数组排序
代码如下所示:
#import <Foundation/Foundation.h>
#import "TRStudent.h"
int main(int argc, const char * argv[])
{
@autoreleasepool {
// insert code here...
TRStudent* stu1 = [[TRStudent alloc]init];
stu1.age = 18;
stu1.name = @"zhangsan";
TRStudent* stu2 = [[TRStudent alloc]init];
stu2.age = 19;
stu2.name = @"lisi";
TRStudent* stu3 = [[TRStudent alloc]init];
stu3.age = 20;
stu3.name = @"wangwu";
NSComparisonResult(^compare)(id stu1,id stu2);
compare = ^(id stu1,id stu2)
{
//类型转换
NSString* s1 = nil;
if([stu1 isMemberOfClass:[TRStudent class]])
{
s1 = ((TRStudent*)stu1).name;
}
NSString* s2 = nil;
if([stu2 isMemberOfClass:[TRStudent class]])
{
s2 = ((TRStudent*)stu2).name;
}
return [s1 compare:s2];
};
NSArray* array = @[stu1,stu2,stu3];
NSLog(@"array:%@",array);
NSArray* array2 = [array sortedArrayUsingComparator:compare];
NSLog(@"array2:%@", array2);
}
return 0;
}
上述代码中,以下代码:
NSArray* array = @[stu1,stu2,stu3];
NSLog(@"array:%@",array);
用三个学生对象创建一个数组array。
上述代码中,以下代码:
NSArray* array2 = [array sortedArrayUsingComparator:compare];
向数组对象array发送NSArray类的方法sortedArrayUsingComparator:消息,使用Block变量compare作为实参,传递一个排序方法,在该消息内对数组内的所有数组元素进行排序,并将排序的结果生成一个新的数组返回。
1.4 完整代码
本案例中,类TRStudent声明,即TRStudent.h文件,完整代码如下所示:#import <Foundation/Foundation.h>
@interface TRStudent : NSObject
@property(nonatomic,assign)int age;
@property(nonatomic,copy)NSString* name;
@end
类TRStudent实现,即TRStudent.m文件,完整代码如下所示:
#import "TRStudent.h"
@implementation TRStudent
-(NSString *)description{
return [NSString stringWithFormat:@"age:%d name:%@",self.age,self.name];
}
@end
主程序,即main.m,完整代码如下所示:
#import <Foundation/Foundation.h>
#import "TRStudent.h"
int main(int argc, const char * argv[])
{
@autoreleasepool {
// insert code here...
TRStudent* stu1 = [[TRStudent alloc]init];
stu1.age = 18;
stu1.name = @"zhangsan";
TRStudent* stu2 = [[TRStudent alloc]init];
stu2.age = 19;
stu2.name = @"lisi";
TRStudent* stu3 = [[TRStudent alloc]init];
stu3.age = 20;
stu3.name = @"wangwu";
NSComparisonResult(^compare)(id stu1,id stu2);
compare = ^(id stu1,id stu2)
{
//类型转换
NSString* s1 = nil;
if([stu1 isMemberOfClass:[TRStudent class]])
{
s1 = ((TRStudent*)stu1).name;
}
NSString* s2 = nil;
if([stu2 isMemberOfClass:[TRStudent class]])
{
s2 = ((TRStudent*)stu2).name;
}
return [s1 compare:s2];
};
NSArray* array = @[stu1,stu2,stu3];
NSLog(@"array:%@",array);
NSArray* array2 = [array sortedArrayUsingComparator:compare];
NSLog(@"array2:%@", array2);
}
return 0;
}
相关文章推荐
- poj 1821(DP+单调队列优化)
- windows php安装ImageMagick扩展
- C#中listview 选中一行并把对应的几列数据放到textbox中
- 美国人这样教育小学生
- hdoj5585Numbers
- JAVA设计模式之享元模式
- bzoj3620(KMP)
- NSDictionary 、 NSMutableDictionary
- 关于oracle with as用法
- NSArray(二) 、 NSMutableArray 、 NSSet 、 NSMutableSet
- 代码对比看:&& || %errorlevel%的区别
- 互联网协议入门(一)
- python :逻辑行被分成两个物理行的解决方法
- hdoj2803The MAX
- JAVA设计模式之门面模式(外观模式)
- NSNumber 、 NSValue 、 日期处理 、 集合类 、 NSArray(一)
- [深入Maven源代码]maven绑定命令行参数到具体插件
- StringUtils中 isNotEmpty 和isNotBlank的区别
- Mysql Cluster基于时间点的恢复
- Java基础---网络编程