AFFEvent 1.4.1

AFFEvent 1.4.1

测试已测试
语言语言 Obj-CObjective C
许可证 MIT
发布最后发布2015年3月

Jeremy Fuellert维护。



AFFEvent 1.4.1

  • 作者
  • Jeremy Fuellert

AFFEvent是为iOS和OSX应用程序构建的替代事件系统。该事件系统具有可变的事件系统,允许您添加、删除和修改事件以及/或处理程序和块。它还允许在事件被触发时调用具有多个参数的方法和块。

目的

该软件的目的是为开发者提供处理iOS事件的一种替代方式。其主要目标是最小化在不需要的情况下使用代理。通过消除对代理的需求,类对事件有更多的控制权,可以用它们做独特的事情,包括使用另一个类的实例事件触发一个类,使用类事件,或触发一次性事件。

支持

IOS

最早测试和受支持的构建和部署目标 - iOS 5.0。最新测试和受支持的构建和部署目标 - iOS 7.0。

OSX

最早测试和受支持的构建和部署目标 - OSX 10.6。最新测试和受支持的构建和部署目标 - OSX 10.8。

ARC兼容性

AFFEvent是从非ARC构建的,目前不支持ARC。当使用ARC时,请在项目的构建阶段为AFFEvent文件使用编译器标志'-fno-objc-arc'。

安装

将AFFEvent文件夹及其内容复制到项目中。请确保始终使用最新发布的二进制文件进行最简单、最稳定的安装。将以下行添加到您的-Prefix.pch文件中

#import "AFFEventCenter.h"

(此处省略了具体代码,因为原英文文本未包含具体代码。)

事件使用

关于

事件通过一个中央系统处理,类似于NSNotificationCenter。事件不使用“名称”约定或代理;相反,它们使用对象的hash与类中独特的方法名称组合。如果需要,您可以通过全局AFFEventSystemHandler类修改事件,但推荐的方式是通过事件方法本身修改事件。

对于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方法在任何时候更改事件处理。这些方法也可以链接。

锁定/解锁处理程序和块

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

变更日志

  • 2013年8月9日:发布 1.3.1。这是一个小修补程序,更改了处理程序的默认后台线程队列优先级。
  • 2013年8月6日:发布 1.3.0。此版本通过允许在后台线程中执行,对小范围的选择器和块处理程序进行了小的增加。
  • 2013年8月5日:发布 1.2.0。这是一个小的特性发布,扩展了对块的支持。
  • 2013年8月5日:确认与 MAC OSX 1.06 - 1.08 兼容。
  • 2013年8月5日:发布 1.1.0。此版本增加了新功能块支持,功能类似于选择器处理程序,以及错误修复。
  • 2013年8月4日:增加了在使用事件监听时使用块的选项,这将为更多的简洁性和灵活性提供支持。
  • 2013年7月31日:由于泄漏暂时移除 ARC 支持(1.0.1)。
  • 2013年7月30日:发布 1.0.0。第一个稳定版本。
  • 2013年7月28日:添加了 AFFEventAPI 锁定和解锁功能。这将为事件的处理程序提供更多的控制。
  • 2013年7月25日:增加了性能调整。