> On Nov 10, 2017, at 2:57 PM, Joe Groff <jgr...@apple.com> wrote:
> 
>> On Nov 10, 2017, at 12:37 PM, Charles Srstka <cocoa...@charlessoft.com 
>> <mailto:cocoa...@charlessoft.com>> wrote:
>> 
>>> On Nov 10, 2017, at 12:04 PM, Joe Groff via swift-evolution 
>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>> 
>>> I don't like the idea of some calls having wildly different semantics from 
>>> others; it's difficult enough to tell what exactly a call might be doing 
>>> already. Since we also lack the more obvious static "Callable" protocol 
>>> idea to give even well-typed call syntax to user-defined types, this also 
>>> seems like it'd be easily abused for that purpose too.
>> 
>> We already have that though, with the Objective-C bridge. How is the 
>> proposed behavior here more wildly different than the semantics of 
>> non-@objc, @objc, and @objc dynamic calls?
> 
> The language semantics aren't any different for non-@objc or @objc calls. The 
> dispatch mechanism is an implementation detail. `dynamic` admits the 
> possibility of late binding to change the method implementation dynamically, 
> but doesn't change the type system behavior of the method, or radically 
> change the implementation mechanism; it's still ultimately an indirect call, 
> it doesn't turn your argument list into a dictionary that can be arbitrarily 
> interpreted by user code.
> 
> -Joe

You sure about that? ;-)

MyObject.h:

#import <Foundation/Foundation.h>

@interface MyObject : NSObject

@property (nonatomic, copy) void (^callback)(NSDictionary *);

@end

@interface MyObject (MyCategory)

- (void)foo:(NSString *)foo bar:(NSString *)bar;

@end

MyObject.m:

#import "MyObject.h"

@implementation MyObject

- (void)baz:(NSString *)baz qux:(NSString *)qux {}

- (NSMethodSignature *)methodSignatureForSelector:(SEL)selector {
    if (selector == @selector(foo:bar:)) {
        return [super methodSignatureForSelector:@selector(baz:qux:)];
    } else {
        return [super methodSignatureForSelector:selector];
    }
}

- (void)forwardInvocation:(NSInvocation *)invocation {
    NSString *name = NSStringFromSelector(invocation.selector);
    NSMutableArray *args = [NSMutableArray new];
    
    for (NSUInteger i = 2; i < invocation.methodSignature.numberOfArguments; 
i++) {
        __unsafe_unretained id obj = nil;
        
        [invocation getArgument:&obj atIndex:i];
        
        [args addObject:obj];
    }
    
    self.callback(@{ @"name" : name, @"arguments" : args });
}

@end

main.swift:

import Foundation

let obj = MyObject()

obj.callback = { dict in
    print("got this dictionary: \(dict as? [String : Any] ?? [:])")
}

obj.foo("Foo", bar: "Baz”)

Charles

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to