我想测试块函数和上下文的值。测试代码是:
//xxx.h
@interface textObj : NSObject
@property (nonatomic, retain) NSNumber * num;
@end
typedef void (^ returnHandle)(NSNumber * res);
@interface BlockTest : NSObject
- (void) textBlock:(textObj *)num completionHandler:(void (^)(NSNumber * res))handler;
@end//xxx.m
@implementation textObj
@synthesize num;
@end
@interface BlockTest (){
returnHandle rt;
}
- (void)toggleChromeDisplay;
@end
@implementation BlockTest
- (void) dealloc{
Block_release(rt);
[super dealloc];
}
- (void)toggleChromeDisplay
{
NSNumber *ret = [NSNumber numberWithInt:111];
rt(ret);
}
void (^handle)(NSNumber * res, NSError *error);
- (void) textBlock:(textObj *)g1 completionHandler:(void (^)(NSNumber * res))handler
{
rt = Block_copy(handler);
[self performSelector:@selector(toggleChromeDisplay) withObject:nil afterDelay:0.5];
return;
}
@end测试示例调用代码是:
//first sample code...
- (void)viewDidLoad
{
[super viewDidLoad];
test = [[BlockTest alloc]init];
textObj * g1;
g1 = [[textObj alloc] init];
[g1 setNum:[NSNumber numberWithInt:10]];
NSLog(@"main 0 g1 num=%@ count=%d", [g1 num], [g1 retainCount]);
[test textBlock:g1 completionHandler:^(NSNumber *res) {
NSLog(@"value=%@", [g1 num]);
[g1 setNum:[NSNumber numberWithInt:20]];
NSLog(@"main 1 g1 num=%@ count=%d", [g1 num], [g1 retainCount]);
} ];
NSLog(@"main 2 g1 num=%@ count=%d", [g1 num], [g1 retainCount]);
[g1 release];
NSLog(@"main 3 g1 num=%@ count=%d", [g1 num], [g1 retainCount]);
}在块函数中,我可以更改g1值。没问题。但是,当我将g1声明为测试的公共值时,它将在块函数中出错。g1不能被访问。输出EXC_BAD_ACCESS(code=2,address=0x26)错误。
//second sample code...
@interface UIMainViewController (){
@public
textObj * g1;
}
@end
- (void)viewDidLoad
{
[super viewDidLoad];
test = [[BlockTest alloc]init];
//textObj * g1;
g1 = [[textObj alloc] init];
[g1 setNum:[NSNumber numberWithInt:10]];
NSLog(@"main 0 g1 num=%@ count=%d", [g1 num], [g1 retainCount]);
[test textBlock:g1 completionHandler:^(NSNumber *res) {
NSLog(@"value=%@", [g1 num]);
[g1 setNum:[NSNumber numberWithInt:20]];
NSLog(@"main 1 g1 num=%@ count=%d", [g1 num], [g1 retainCount]);
} ];
NSLog(@"main 2 g1 num=%@ count=%d", [g1 num], [g1 retainCount]);
[g1 release];
NSLog(@"main 3 g1 num=%@ count=%d", [g1 num], [g1 retainCount]);
}我混淆了两个不同的样本代码,为什么第二个测试代码会遇到崩溃?
发布于 2012-06-20 18:27:19
主要问题是,正如@H2CO3所指出的,在执行块之前,您正在释放g1。它在一种情况下而不是另一种情况下工作的原因是块保留它们在复制时引用的任何本地对象变量。。
在第一个示例中,g1是方法作用域的局部变量,因此块保留它。
在第二个示例中,g1是一个ivar (实际上是self->g1),因此块保留了self。但是在声明块之后立即释放g1,所以当块调用self->g1时,它会得到一个无效的指针,因为g1已被解除分配。
发布于 2012-06-20 14:41:18
retainCount没用。别叫了。永远不会。
根据定义,retainCount不能返回零。您正在发送消息给一个未定义的、经常崩溃的已释放对象。
https://stackoverflow.com/questions/11115473
复制相似问题