5

我需要使用 swift 在 iOS 中创建代理模式

我已经使用Objective C尝试过,这里是代码

我的协议.h

#import <Foundation/Foundation.h>
@protocol MyProtocol <NSObject>
@required
-(void)testMessage;    
@end

测试BO.h

#import <Foundation/Foundation.h>
#import "MyProtocol.h"

@interface TestBO : NSObject <MyProtocol>

@end

测试BO.m

#import "TestBO.h"

@implementation TestBO 

-(void)testMessage{
    NSLog(@"Test Message");
}

@end

测试代理处理程序.h

#import <Foundation/Foundation.h>

@interface TestProxyHandler : NSProxy

@property (nonatomic, strong) id object;

- (instancetype)initWithProtocol:(Protocol *)protocol andObject:(Class)clazz;

- (void)forwardInvocation:(NSInvocation *)invocation;

- (NSMethodSignature *)methodSignatureForSelector:(SEL)selector;

@end

测试代理处理程序.m

#import "TestProxyHandler.h"
#import "TestBO.h"

@implementation TestProxyHandler 

- (instancetype)initWithProtocol:(Protocol *)protocol andObject:(Class)clazz{
    if ([clazz conformsToProtocol:@protocol(MyProtocol)]) {
        self.object = [[clazz alloc] init];
    }else{
        NSLog(@"Error it does not conform to protocol");
    }
    return self;
}

- (void)forwardInvocation:(NSInvocation *)invocation{
    NSString *selString = NSStringFromSelector(invocation.selector);
    NSLog(@"Called %@",selString);
    [invocation invokeWithTarget:self.object];
}

- (NSMethodSignature *)methodSignatureForSelector:(SEL)selector {
    return [self.object methodSignatureForSelector:selector];
}


@end

我已经调用它使用

id <MyProtocol> delegate = (TestBO *)[[TestProxyHandler alloc] initWithProtocol:@protocol(MyProtocol) andObject:[TestBO class]];

[delegate testMessage];

但我无法让它在 Swift 中工作,即使初始化程序显示消息

TestHandler.swift

import Foundation
class TestHandler: NSProxy {
    var object: AnyObject

    convenience override init(`protocol`: Protocol, andObject clazz: AnyClass) {
        if clazz.conformsToProtocol() {
            self.object = clazz()
        }
        else {
            NSLog("Error it does not conform to protocol")
        }
    }        
}

有没有人有任何线索可以迅速做到这一点?

编辑:

java中,您可以使用Proxy.newProxyInstance调用创建方法的运行时实现,但这可以在 iOS 中实现吗?使用迅速?有什么线索吗?

4

1 回答 1

2

与 Objective C 和 Swift 相比,Swift 提供了极其有限的运行时语言访问权限。所以根据我到目前为止的研究,它不能完成:(

我什至尝试在 swift 中对NSProxy类进行子类化,但无法调用super.init并且代码永远不会编译,但是同样的事情在目标 C 中也有效

所以我最终采用了这种方法

我使用创建了一个协议

@objc protocol SomeProt {
    // Some method
}

注意协议之前的关键字@objc 是必不可少的,否则您将无法将其作为变量传递,还添加@objc将协议的使用限制为目标c 运行时功能,因此不要期望在swift 中获得协议的全部功能

public func someMethod(`protocol` : Protocol, implementation : AnyClass) {
    let isImplemented : Bool = implementation.conformsToProtocol(`protocol`)
        // some code
}

如果您需要在某些字典或应符合NSCopying类的地方使用它,请使用

NSStringFromProtocol

NSProtocolFromString

方法

现在我写了一个客观的c帮助类来做初始化

ObjcHelper.h

#import <Foundation/Foundation.h>

@interface ObjcHelper : NSObject
+(NSObject *)objectForClass:(Class)clazz;
@end

ObjcHelper.m

#import "ObjcHelper.h"

@implementation ObjcHelper
+ (NSObject *)objectForClass:(Class)clazz{
    return [[clazz alloc] init];
}
@end

现在使用它

let prot : SomeProt = ObjcHelper.objectForClass(NSClassFromString("PROT_HANDLER_CLASS_NAME")) as! SomeProt

但是,将来如果有人可以提供更好的答案,请务必在此处发布

于 2016-01-25T18:50:49.800 回答