#import <Foundation/Foundation.h>
typedef int (^IntBlock)();
@interface myobj : NSObject
{
IntBlock compare;
}
@property(readwrite, copy) IntBlock compare;
@end
@implementation myobj
@synthesize compare;
- (void)dealloc
{
// need to release the block since the property was declared copy. (for heap
// allocated blocks this prevents a potential leak, for compiler-optimized
// stack blocks it is a no-op)
// Note that for ARC, this is unnecessary, as with all properties, the memory management is handled for you.
[compare release];
[super dealloc];
}
@end
int main () {
@autoreleasepool {
myobj *ob = [[myobj alloc] init];
ob.compare = ^
{
return rand();
};
NSLog(@"%i", ob.compare());
// if not ARC
[ob release];
}
return 0;
}
现在,如果需要更改比较类型,唯一需要更改的就是typedef int (^IntBlock)(),如果需要向它传递两个对象,请将其更改为:typedef int (^IntBlock)(id, id),并将块更改为:
// Here is a block as a property:
//
// Someone passes you a block. You "hold on to it",
// while you do other stuff. Later, you use the block.
//
// The property 'doStuff' will hold the incoming block.
@property (copy)void (^doStuff)(void);
// Here's a method in your class.
// When someone CALLS this method, they PASS IN a block of code,
// which they want to be performed after the method is finished.
-(void)doSomethingAndThenDoThis:(void(^)(void))pleaseDoMeLater;
// We will hold on to that block of code in "doStuff".
您的. m文件:
-(void)doSomethingAndThenDoThis:(void(^)(void))pleaseDoMeLater
{
// Regarding the incoming block of code, save it for later:
self.doStuff = pleaseDoMeLater;
// Now do other processing, which could follow various paths,
// involve delays, and so on. Then after everything:
[self _alldone];
}
-(void)_alldone
{
NSLog(@"Processing finished, running the completion block.");
// Here's how to run the block:
if ( self.doStuff != nil )
self.doStuff();
}
let resultTrailingClosure = test { return "TRAILCLOS_" + $0 + "__TRAILCLOS" }
最后: 使用所有这些功能,我将混合使用尾随闭包和类型推断(为了可读性而命名)
PFFacebookUtils.logInWithPermissions(permissions) {
user, error in
if (!user) {
println("Uh oh. The user cancelled the Facebook login.")
} else if (user.isNew) {
println("User signed up and logged in through Facebook!")
} else {
println("User logged in through Facebook!")
}
}
8条答案
按热度按时间yqyhoc1h1#
如果要在多个位置重复相同的块,请使用type def
lkaoscv72#
下面是一个如何完成此类任务的示例:
现在,如果需要更改比较类型,唯一需要更改的就是
typedef int (^IntBlock)()
,如果需要向它传递两个对象,请将其更改为:typedef int (^IntBlock)(id, id)
,并将块更改为:编辑2012年3月12日:
对于ARC,不需要做任何特定的更改,因为只要块被定义为复制,ARC就会为您管理块。您也不需要在析构函数中将该属性设置为nil。
欲了解更多阅读,请查看此文档:http://clang.llvm.org/docs/AutomaticReferenceCounting.html
kr98yfug3#
@属性(副本)无效
就这么简单。
以下是实际的Apple文档,其中详细说明了如何使用:
Apple doco.
您的. h文件:
您的. m文件:
小心过期的示例代码。
使用现代(2014年以上)系统,按照这里所示做。就是这么简单。
vc6uscn94#
为了后代/完整性的缘故...这里有两个完整的例子,如何实现这种可笑的通用“做事方式”。@罗伯特的答案是幸福的简洁和正确的,但在这里我也想展示如何实际“定义”的块。
愚蠢?* 是的。* 有用?***当然。***这里有一种不同的、“更原子化”的设置属性的方法...和一个非常有用的类...
这说明了通过访问器设置block属性(虽然在init内部,但这是一个有争议的冒险实践..)与第一个示例的“非原子”“getter”机制。在任何一种情况下..“硬编码”实现总是可以被覆盖,* 每个示例 *..
另外,如果你想在一个类别中添加一个块属性...假设你想使用一个块而不是一些老派的目标/动作“动作”...你可以只使用关联的值来关联块。
现在,当你制作一个按钮时,你不需要设置一些
IBAction
戏剧..只要把要在创作时完成的工作联系起来...这种模式可以反复应用于 * 可可API。使用属性将代码的相关部分 * 紧密地结合在一起 *,消除 * 复杂的委托范例 *,并利用对象的强大功能,而不仅仅是充当哑“容器”。
5us2dqdw5#
当然,你可以把块作为属性使用。但是要确保它们声明为**@property(copy)**。例如:
在MRC中,捕获上下文变量的块被分配在堆栈中;当堆栈帧被销毁时,它们将被释放。2如果它们被复制,一个新的块将被分配到堆中,它可以在堆栈帧弹出后执行。
6pp0gazn6#
放弃者
这并不是一个"好答案",因为这个问题是针对ObjectiveC的。由于苹果在WWDC14上介绍了Swift,我想分享一下在Swift中使用块(或闭包)的不同方法。
∮你好,斯威夫特
在Swift中,有很多方法可以传递与函数等价的块。
我找到三个。
为了理解这一点,我建议你在操场上测试这一小段代码。
Swift,针对密封件进行了优化
由于Swift针对异步开发进行了优化,苹果在闭包上做了更多的工作。
按数字访问参数
使用命名进行参数推断
尾部闭合
这种特殊情况只有在块是最后一个参数时才有效,它被称为 * 尾随闭包 *
以下是一个示例(与推断签名合并以显示Swift的强大功能)
最后:
使用所有这些功能,我将混合使用尾随闭包和类型推断(为了可读性而命名)
xtupzzrd7#
"你好,斯威夫特"
补充"弗朗切斯库“的回答。
添加额外参数:
ezykj2lf8#
您可以遵循下面的格式并使用类中的
testingObjectiveCBlock
属性。有关详细信息,请查看here