在 JavaScriptCore 中使用 NSBlock 作为 属性
Use a NSBlock as a property in JavaScriptCore
我需要使用 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 中不可扩展,因此引入新字段将被忽略。
如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)();
}
我需要使用 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 中不可扩展,因此引入新字段将被忽略。
如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)();
}