2014-07-06 14 views
7

मैं यह जानने का प्रयास कर रहा हूं कि जावास्क्रिप्ट को तेजी से कैसे उपयोग करें। मैं समस्याओं में भाग रहा हूं, हालांकि जब मुझे तर्कों के रूप में ब्लॉक से निपटना पड़ता है, ऐसा लगता है कि ब्लॉक तुरंत चलाया जाता है और तर्कों को ब्लॉक का रिटर्न वैल्यू मिलता है। मैं क्या गलत कर रहा हूं?स्विफ्ट ब्लॉक काम नहीं कर रहे

कार्य उद्देश्य सी कोड:

JSContext* context = [[JSContext alloc] initWithVirtualMachine:[[JSVirtualMachine alloc] init]]; 
context[@"test"] = ^(NSString *string) { 
    //code 
}; 

मैं क्या कोशिश की है:

1:

var ctx = JSContext(virtualMachine:JSVirtualMachine()) 
var ctx["test"] = {(string:NSString)->() in /*code*/ } 

//Gives me "'JSContext' does not have a member named 'subscript'" 

2:

var ctx = JSContext(virtualMachine:JSVirtualMachine()) 
let n: (string: String)->() = {string in /*code*/} 

ctx.setObject(n, forKeyedSubscript:"test") 

//Gives me "Type '(x: String) ->() does not conform to protocol 'AnyObject'" 

3:

var ctx = JSContext(virtualMachine:JSVirtualMachine()) 
let n: (string: String)->() = {string in /*code*/} 

ctx.setObject(n as AnyObject, forKeyedSubscript:"test") 

//Gives me "Cannot downcast from '(string: String) ->() to [email protected] protocol type 'AnyObject'" 

क्या मुझे यहां कुछ याद आ रहा है, या यह स्विफ्ट में बस एक बग है?

संपादित करें: से Cast closures/blocks

class Block<T> { 
    let f : T 
    init (_ f: T) { self.f = f } 
} 

मैं अब भी कोशिश की है सुझाव और फिर

ctx.setObject(Block<()->Void> { 
     /*code*/ 
    }, forKeyedSubscript: "test") 

यह समाधान मुझे संकलन की सुविधा देता है, लेकिन मैं एक रनटाइम त्रुटि मिलती है:

Thread 1: EXC_BREAKPOINT (code=EXC_I386_BPT, subcode=0x0) 
+0

इस जैसा ही समस्या है: http://stackoverflow.com/questions/24586293/cast-closures-blocks। –

+0

यह समान लेकिन अलग है। यह सवाल * ओबीजेसी विधियों से * रिटर्न वैल्यू * के रूप में प्राप्त ब्लॉकों से निपटने के बारे में है। यह * ओबीजेसी विधियों के लिए ब्लॉक * के रूप में स्विफ्ट बंद करने के बारे में है। –

उत्तर

26

स्विफ्ट को बंद करने के तरीके के साथ इसका कुछ संबंध है। आपको एनबीजेसी ब्लॉक बंद करने के लिए @convention(block) का उपयोग करने की आवश्यकता है। unsafeBitCast का प्रयोग करें यह

var block : @convention(block) (NSString!) -> Void = { 
    (string : NSString!) -> Void in 
    println("test") 
} 

ctx.setObject(unsafeBitCast(block, AnyObject.self), forKeyedSubscript: "test") 

आरईपीएल

से
swift 
Welcome to Swift! Type :help for assistance. 
    1> import Foundation 
    2> var block : @convention(block)(NSString!) -> Void = {(string : NSString!) -> Void in println("test")} 
block: @convention(block)(NSString!) -> Void = 
    3> var obj: AnyObject = reinterpretCast(block) as AnyObject 
obj: __NSMallocBlock__ = {} // familiar block type 
+0

यह एक आकर्षण की तरह काम किया! बहुत बहुत धन्यवाद। केवल एक चीज, जाहिर है 'सीटीएक्स ["परीक्षण"] = 'काम नहीं करता है। 'ctx.setObject (obj, forKeded सदस्यता:" परीक्षण ") हालांकि। एक बार फिर, धन्यवाद, और जब मैं सक्षम हूं तो 22 घंटों में आपका बक्षीस है। – hannesr

+0

बीटा 6 'reinterpretCast (ब्लॉक) पर AnyOfeject' को' unsafeBitCast (ब्लॉक, AnyObject) ' –

+4

के पक्ष में बहिष्कृत कर दिया गया है, वास्तव में, यह 'असुरक्षित बिटकास्ट (ब्लॉक, AnyObject' होगा।स्वयं) ' –

1

डाली मजबूर करने के लिए मैं एक काम कर डेमो है

और यहाँ बात यह है कि ब्लॉक लागू करता है पंजीकरण:

typealias ID = AnyObject! 
extension JSContext { 
    func fetch(key:NSString)->JSValue { 
     return getJSVinJSC(self, key) 
    } 
    func store(key:NSString, _ val:ID) { 
     setJSVinJSC(self, key, val) 
    } 
    func store(key:NSString, _ blk:()->ID) { 
     setB0JSVinJSC(self, key, blk) 
    } 
    func store(key:NSString, _ blk:(ID)->ID) { 
     setB1JSVinJSC(self, key, blk) 
    } 
    func store(key:NSString, _ blk:(ID,ID)->ID) { 
     setB2JSVinJSC(self, key, blk) 
    } 
} 

आपको इसे काम करने के लिए एक बहुत ही छोटे ओबीजेसी कोड और ब्रिजिंग हेडर की आवश्यकता है। विवरण के लिए भंडार देखें।

संबंधित मुद्दे