我以前也问过类似的问题,但这次情况有点不同。
一方面,这一次我使用了 ARC(引发了一个全新的问题世界)。第二:我的代码基本上可以工作,但我想知道我是否可以用更少的代码来做。
现在,我的代码如下所示:
__weak CustomType *Object;
void (^doAverage)(CustomType *, int, int) = ^(CustomType *Trigger, int Val1, int Val2) {
//Calculations with Trigger
}
CustomType *(^Add)(int, CustomType *) = ^(int Val1, CustomType *NewObject) {
//Checks prerequisites, and returns either the passed object after adding it to
//an array or nil, if the prerequisites haven't been met.
}
现在,更进一步,我正在这样做:
Object = Add(-1, [CustomType makeObjectWithParameters]);
[Object addCallback:^{ doAverage(Object, 56, 57); }];
在内部addCallback
,带有调用的传递块doAverage
被发送一条copy
消息并保存以供以后执行。
这有效,没有保留周期,如果对象被释放,回调折叠。
但这并不像我想要的那样“优雅”。
我想要的是这些方面的东西:
__block __weak CustomType *Object;
CustomType *(^Add)(int, CustomType *) = ^(int Val1, CustomType *NewObject) {
//Checks prerequisites, and returns either the passed object after adding it to
//an array or nil, if the prerequisites haven't been met.
Object = NewObject;
}
更进一步:
[Add(-1, [CustomType makeObjectWithParameters]) addCallback:^{ doAverage(Object, 56, 57); }];
但是,如果我这样做,它会将Object
传递给回调的内容更改为Add
我最后调用的任何内容,这不是我想要的。
基本上我需要一个块中set
的值,Object
然后copy
将该引用作为参数,而不是将引用传递给变量本身。
此外,作为第二步,如果我不必首先传递参数Object
,但可以在块中使用它,那将是完美的。但是如果我这样做,当块最终被调用时,块中的变量将默认为 nil(远远超过它定义的范围的到期)。
所以而不是:
void (^doAverage)(CustomType *, int, int) = ^(CustomType *Trigger, int Val1, int Val2) {
//Calculations with Trigger
}
我想使用:
void (^doAverage)(int, int) = ^(int Val1, int Val2) {
//Calculations with Object
}
Object
无论当时的价值(弱参考)有什么价值。
两者中的任何一个都有可能吗?
非常感谢。
编辑:
按照以下建议,我重构了我的代码,如下所示:
typedef BOOL (^stackBlock_t)();
typedef BOOL (^CallBlock_t)(__weak id Object);
-(void) addCallback(CallBlock_t)B {
stackBlock_t stackBlock = ^{
__weak id Object = self;
return B(Object);
};
Callback = [stackBlock copy];
}
我试图用以下方式调用这个构造:
[Add(-1, CustomType makeObjectWithParameters]) addCallBack:^{ doAverage(Object, 56, 57); }];
但是由于某种原因Object
没有为块定义doAverage
,我不太清楚为什么。毕竟,它是一个 type 块CallBlock_t
,它接受一个 type 参数id
和 name Object
。那么它不应该“知道”变量Object
吗?
编辑2:经过一番修改(即使用实际类型和东西),它现在给了我一个不同的错误消息:Incompatible block pointer types sending 'void (^)(void)' to parameter of type 'CallBlock_t'
虽然我不是。我希望该块返回 aBOOL
并接受参数Object
......我做错了什么?
编辑3:我可能已经找到了。我在addCallback
通话中遗漏了一些东西。我还没有测试它,但似乎我需要这样称呼它:
[Add(-1, CustomType makeObjectWithParameters]) addCallBack:^(CustomObject *Object){ doAverage(Object, 56, 57); }];
仔细想想,说的有道理……看的眼花缭乱,但说的有道理。它就像一个魅力。我什至不再需要多余的类型变量__block
。