我需要使用NSBlock作为可在JavaScript中更改的属性。
@protocol ExportingUser <NSObject, JSExport>
@property (nonatomic, copy) void (^changedName) (void);
@property (nonatomic) NSString* name;
@end
我基本上想从Obj-C调用changedName,这是一个定义来自JavaScript的函数。像这样:
user.name = "Peyman"; // this will change the name property in the Obj-C as well.
user.changedName = function() { console.log("yay"); } // but this doesn't
我知道这可以通过JSValue的 callWithArguments 方法实现,但如果可能,我更喜欢这种方法。
编辑:实际上,我认为 callWithArguments 方法无效。这是可能的,因为绑定到Objective-C类的对象在JavaScript中是不可扩展的,因此引入新字段将被忽略。
答案 0 :(得分:0)
如JSValue.h中所列:
// Objective-C type | JavaScript type
// --------------------+---------------------
// nil | undefined
// NSNull | null
// NSString | string
// NSNumber | number, boolean
// NSDictionary | Object object
// NSArray | Array object
// NSDate | Date object
// NSBlock * | Function object *
// id ** | Wrapper object **
// Class *** | Constructor object ***
//
// * Instances of NSBlock with supported arguments types will be presented to
// JavaScript as a callable Function object. For more information on supported
// argument types see JSExport.h. If a JavaScript Function originating from an
// Objective-C block is converted back to an Objective-C object the block will
// be returned. All other JavaScript functions will be converted in the same
// manner as a JavaScript object of type Object.
显然,你可以逃脱:
@property (nonatomic, copy) JSValue* changedName;
然后,当你想要打电话时:
typedef void (^nameChangedBlock)(void);
nameChangedObject = [self.changedName toObject];
if ([nameChangedObject isKindOfClass: NSClassFromString(@"NSBlock")]){
((nameChangedBlock)nameChangedObject)();
}