AFFEvent是为iOS和OSX应用程序构建的替代事件系统。该事件系统具有可变的事件系统,允许您添加、删除和修改事件以及/或处理程序和块。它还允许在事件被触发时调用具有多个参数的方法和块。
该软件的目的是为开发者提供处理iOS事件的一种替代方式。其主要目标是最小化在不需要的情况下使用代理。通过消除对代理的需求,类对事件有更多的控制权,可以用它们做独特的事情,包括使用另一个类的实例事件触发一个类,使用类事件,或触发一次性事件。
最早测试和受支持的构建和部署目标 - iOS 5.0。最新测试和受支持的构建和部署目标 - iOS 7.0。
最早测试和受支持的构建和部署目标 - OSX 10.6。最新测试和受支持的构建和部署目标 - OSX 10.8。
AFFEvent是从非ARC构建的,目前不支持ARC。当使用ARC时,请在项目的构建阶段为AFFEvent文件使用编译器标志'-fno-objc-arc'。
将AFFEvent文件夹及其内容复制到项目中。请确保始终使用最新发布的二进制文件进行最简单、最稳定的安装。将以下行添加到您的-Prefix.pch文件中
#import "AFFEventCenter.h"
关于
对于AFFEvent,提供了两个事件级别。AFFEventInstance为其类定义了一个实例事件,只有通过该类的实例才能访问。AFFEventClass为其类定义了一个类事件,它可能可以从任何地方访问,从该类的任何方法类型触发。
事件在类的头文件中创建,并在实现文件中使用宏进行综合。这些宏实际上为类创建类和/或实例方法,因此被视为常规Objective-C方法。
头文件
AFFEventCreate( $eventLevel, $eventName )
//@param : $eventLevel
//@type : Macro
//@options : AFFEventClass, AFFEventInstance
//@param : $eventName
//@type : NSString
实现文件
AFFEventSynthesize( $eventLevel, $eventName )
//@param : $eventLevel
//@type : Macro
//@options : AFFEventClass, AFFEventInstance
//@param : $eventName
//@type : NSString
AFFEventAPI对象是处理程序交互的容器对象。您可以在其中发送事件、检查处理程序或块、锁定和解锁处理程序或块、添加处理程序、添加块、删除处理程序和删除块。可以使用任何AFFEventAPI方法在任何时候更改事件处理。这些方法也可以链接。
AFFEventAPI对象控制其处理程序和块对应物,因此它们具有添加、删除或在本例中锁定和解锁任何处理程序和块的能力。锁定处理程序方法或块意味着该方法或块在发送事件时不会被触发。处理程序或块不会从事件处理程序列表中删除,这样它就可以在解锁后被再次使用。方法处理程序和块的锁定和解锁在需要暂时禁用交互的情况下特别有用;比如说,当弹出菜单处于活动状态时,它阻止用户界面中的其他元素进行交互。以下是AFFEvent提供的一些锁定和解锁方法。
//Handler lock methods
- (void)lockHandler:(AFFEventHandler *)handler;
- (void)unlockHandler:(AFFEventHandler *)handler;
- (void)lockHandlers:(NSSet *)handlers;
- (void)unlockHandlers:(NSSet *)handlers;
- (void)lockHandlers;
- (void)unlockHandlers;
- (NSSet *)lockedHandlers;
- (NSSet *)unlockedHandlers;
- (BOOL)isHandlerLocked:(AFFEventHandler *)handler;
//Block lock methods
- (void)lockBlockByName:(NSString *)blockName;
- (void)unlockBlockByName:(NSString *)blockName;
- (void)lockBlocksByNames:(NSSet *)blockNames;
- (void)unlockBlocksByNames:(NSSet *)blockNames;
- (void)lockBlocks;
- (void)unlockBlocks;
- (NSSet *)lockedBlocks;
- (NSSet *)unlockedBlocks;
- (BOOL)isBlockLocked:(NSString *)blockName;
处理程序锁定应该在创建处理程序事件之外调用类。这意味着不应从'self'调用'[[self $eventName] lockHandlers]'或'[[self $eventName] unlockHandlers]'。
创建事件所在的类也负责在该类的析构函数中销毁该事件。这可以通过在类的作用域的析构函数中使用AFFRemoveAllEvents()轻松完成。这将从AFFEventSystemHandler中删除该类的所有事件对象。要从一个类中删除特定事件,请使用AFFRemoveEvent( $eventName )。
AFFRemoveAllEvents()
AFFRemoveEvent( $eventName )
//@param: $eventName
//@type : NSString
事件可以由创建事件的类和/或外部类发送。任何监听该事件的处理程序都将被调用,并将发送一个AFFEvent对象供监听器的方法使用。事件可以带数据或不带数据发送给所有监听器。
//Send events from class
[[self $eventName] send];
[[self $eventName] send:data];
//Send events from an instance of a class
[[instance $eventName] send];
[[instance $eventName] send:data];
可以通过和使用NSNotificationCenter监听事件的方式类似的方式进行事件的监听。要添加处理程序,只需将其添加到要监听的事件,并添加选择器和参数(如果有的话)。
[[class $eventName] addHandler:AFFHandler(@selector(SEL))];
[[instance $eventName] addHandler:AFFHandler(@selector(SEL))];
带有参数
[[class $eventName] addHandler:AFFHandlerWithArgs(@selector(SEL:::::…), arg0, arg1, arg2, arg3…)];
[[instance $eventName] addHandler:AFFHandlerWithArgs(@selector(SEL:::::…), arg0, arg1, arg2, arg3…)];
一次性处理程序是只调用一次然后从事件发送者销毁的处理程序
[[class $eventName] addHandlerOneTime:AFFHandler(@selector(SEL))];
[[instance $eventName] addHandlerOneTime:AFFHandler(@selector(SEL))];
带有参数的一次性处理程序
[[class $eventName] addHandlerOneTime:AFFHandlerWithArgs(@selector(SEL:::::…), arg0, arg1, arg2, arg3…)];
[[instance $eventName] addHandlerOneTime:AFFHandlerWithArgs(@selector(SEL:::::…), arg0, arg1, arg2, arg3…)];
后台线程处理程序
[[class $eventName] addHandlerInBackgroundThread:AFFHandler(@selector(SEL))];
[[instance $eventName] addHandlerInBackgroundThread:AFFHandler(@selector(SEL))];
仅执行一次的后台线程处理程序
[[class $eventName] addHandlerInBackgroundThreadOneTime:AFFHandler(@selector(SEL))];
[[instance $eventName] addHandlerInBackgroundThreadOneTime:AFFHandler(@selector(SEL))];
也可以将块添加为处理程序来监听事件。这通过不同的方式实现,不同于使用选择器,并使用命名约定来组织这些块。如果您不想更改块处理程序,则可以简单地将块名称传递为'nil'。添加块处理程序与添加选择器处理程序类似。
[[class $eventName] addBlock:^(AFFEvent *event){ } withName:name];
[[instance $eventName] addBlock:^(AFFEvent *event){ } withName:name];
一次性处理程序是只调用一次然后从事件发送者销毁的处理程序
[[class $eventName] addBlockOneTime:^(AFFEvent *event){ } withName:name];
[[instance $eventName] addBlockOneTime:^(AFFEvent *event){ } withName:name];
后台线程处理程序
[[class $eventName] addBlockInBackgroundThread:^(AFFEvent *event){ } withName:name];
[[instance $eventName] addBlockInBackgroundThread:^(AFFEvent *event){ } withName:name];
仅执行一次的后台线程处理程序
[[class $eventName] addBlockInBackgroundThreadOneTime:^(AFFEvent *event){ } withName:name];
[[instance $eventName] addBlockInBackgroundThreadOneTime:^(AFFEvent *event){ } withName:name];
从事件检索数据与使用 NSNotification 非常相似。将要触发的事件的 selector 可以有多个参数。如果发送的事件没有数据并且不需要任何发送者信息,那么 selector 不需要包含 AFFEvent 对象参数。
- (void)eventHandler {}
如果事件中有数据被发送,或者需要了解更多关于事件的信息,可以包含一个 AFFEvent 对象参数。
- (void)eventHandler:(AFFEvent *)event {}
一个包含一个或多个其他参数的处理程序必须将其第一个参数设为 AFFEvent 对象。
- (void)eventHandler:(AFFEvent *)event withArg0:(id)arg0 andArg1:(id)arg1 andArg2:(id)arg2 {}
AFFEvent 是发送的对象,就像 NSNotification 一样。事件对象本身有三个可访问的属性
@property (nonatomic, readonly) id sender;
@property (nonatomic, readonly) id data;
@property (nonatomic, readonly) NSString *eventName;
'sender' 属性引用发送事件的对象。'data' 属性是事件发送的数据。'eventName' 属性是发送的事件名称。
以下是一个基本使用 AFFEvents 的示例。首先在头文件中创建事件,然后在实现文件中生成。然后向事件添加一个处理程序作为 selector。'myAction' 方法在触发时,会发送包含数据的事件。这些数据将通过附加到事件的处理程序检索,然后将数据记录下来。
@interface MyClass : NSObject
AFFEventCreate(AFFEventInstance, evtTest);
@end
@implementation MyClass
AFFEventSynthesize(AFFEventInstance, evtTest);
- (id)init
{
[[self evtTest] addHandler:AFFHandler(@selector(myEvent:))];
[self myAction];
}
- (void)myAction
{
[[self evtTest] send:[NSNumber numberWithInt:15]];
}
- (void)myEvent:(AFFEvent *)event
{
int result = [[event data] intValue];
//result will be '15'
}
- (void)dealloc
{
AFFRemoveAllEvents();
[super dealloc];
}
@end