【问题标题】:Swift array of handler blocks处理程序块的 Swift 数组
【发布时间】:2014-09-12 10:13:27
【问题描述】:

在 Objective-c 中,我在 .h 文件中有一段代码:

typedef void(^SocketConnectionLost)();
typedef void(^SocketIOCallback)(id argsData);

@interface SocketConnection

@property (strong, nonatomic) SocketIO *socketIO;

@property (strong, nonatomic) NSMutableArray *socketConnectionLosts;

-(void)sendEventWithName:(NSString*)eventName
                withData:(id)data
        onConnectionLost:(SocketConnectionLost)connectionLost
                onAnswer:(SocketIOCallback)answer;

@end

我在 .m 文件中有一个代码:

@implementation SocketConnection

- (void)init {
    self.socketIO = [[SocketIO alloc] initWithDelegate:self];
    [self.socketIO setReturnAllDataFromAck: YES];
    [self.socketIO connectToHost:kSocketHost onPort:kSocketPort withParams:params];
}

- (void) socketIODidDisconnect:(SocketIO *)socket
         disconnectedWithError:(NSError *)error {
    for(ServerRequestConnectionLost connectionLost in self.socketConnectionLosts)
        if(connectionLost)
            connectionLost();
    [self.socketConnectionLosts removeAllObjects];
}

-(void)sendEventWithName:(NSString*)eventName
                withData:(id)data
        onConnectionLost:(SocketConnectionLost)connectionLost
                onAnswer:(SocketIOCallback)answer {
    [self.socketConnectionLosts addObject:connectionLost];
    [self.socketIO sendEvent:eventName withData:data andAcknowledge:^(id argsData) {
        if(connectionLost)
            [self.socketConnectionLosts removeObject:connectionLost];
        if(answer)
            answer(argsData);
    }];
}

@end

请帮我在 Swift 中重现这段代码,我不明白如何使用 NSArray 上的 Array 创建、添加和删除 Swift 块

这就是我尝试在 Swift 中创建一些块的方式:

var someBlock: ()->()
var connectionLosts = NSMutableArray()
connectionLosts.append(someBlock)

编译器显示错误:类型“()->()”不确认协议“AnyObject”

然后我需要从数组中删除 someBlock,例如 obj-c 中的 [self.socketConnectionLosts removeObject:connectionLost],我不明白如何使用 Swift 数组来完成。

【问题讨论】:

    标签: swift objective-c-blocks


    【解决方案1】:

    您不必使用objective-c 数组,只需使用swift 数组即可。看看这个:

    typealias ClosureType = () -> ()
    
    var someClosure: ClosureType = { println("Closure executed") }
    
    var array = [ClosureType]()
    
    array.append(someClosure)
    
    array[0]()
    

    如果你在操场上运行,最后一行将打印Closure executed

    NSArray 不起作用的原因是它在 swift 中被桥接为 AnyObject 的数组 - 但 AnyObject任何类类型的实例,显然闭包不是一个类。

    至于从数组中删除一个项目,这是一个更复杂的问题。 find 不能使用,因为它需要数组类型来实现Equatable 协议,但是闭包没有实现它,并且它们不能被扩展。

    也许您可以使用字典,而不是使用数组,根据您的应用逻辑使用对您有意义的键类型 - 例如文本名称、枚举等。例如,如果您使用枚举:

    enum ClosureEnum {
        case TEST_ELEMENT
    }
    
    var dict = [ClosureEnum:ClosureType]()
    dict[.TEST_ELEMENT] = someClosure
    dict[.TEST_ELEMENT]!()
    

    注意dict[.TEST_ELEMENT]!() 中的!,这是必需的,因为在字典中查找总是返回一个可选的。您可以像这样使用强制展开,或者将其包含在可选绑定中以获得更安全的代码。

    要删除一个元素,只需使用正确的方法:

    dict.removeValueForKey(.TEST_ELEMENT)
    

    【讨论】:

    • 谢谢!请告诉我如何从数组中删除,我试试这个:array = array.filter({$0 != someClosure}) 但编译器说:类型'ClosureType'不符合协议'Equatable'
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-06
    • 1970-01-01
    • 2014-10-02
    • 2015-12-17
    相关资源
    最近更新 更多