ios - Mutate inout function paramter inside async block -


i have following playground code:

import uikit import xcplayground  class {      var arr : [uiimage] = []      func additem(inout localarr: [uiimage]) {         dispatch_after(dispatch_time(dispatch_time_now, (int64)(2 * nsec_per_sec)), dispatch_get_main_queue()) { () -> void in             localarr.append(uiimage())             print("from inside function localarr: \(localarr)")             print("form inside function: \(self.arr)")         }     } }  let = a() a.additem(&a.arr) print("instant print :\(a.arr)")  dispatch_after(dispatch_time(dispatch_time_now, (int64)(3 * nsec_per_sec)), dispatch_get_main_queue()) { () -> void in     print("print after delay: \(a.arr)") }  xcplaygroundpage.currentpage.needsindefiniteexecution = true 

the output is:

instant print :[] inside function localarr: [<uiimage: 0x7f99e8706f10>, {0, 0}] form inside function: [] print after delay: [] 

my question is, why localarr not same self.arr inside additem , not same a.arr outside? expectation when pass parameter inout should able operate on actual object, not copy, not happens.

edit: dfri answer know why doesn't work. inout call-by-copy-restore, check answer here. now, suggestion on how make closure capture reference original object? or perhaps should use other technique achieve want?

for theory on inout keyword, see following answer:

do not depend on behavioral differences between copy-in copy-out , call reference.

...

when function returns, changes original overwritten value of copy. not depend on implementation of call-by-reference optimization try keep changes being overwritten.

now, additem function finish call , hence complete inout copy-in/copy-out task prior delayed dispatch in function. makes inherently bad use delayed dispatches within method of inout parameters, @ least if delay 1 tries mutate inout parameter.

to see this, lets track references (rather tracking values) of array, , how possibly show mutation of array during runtime of our example.

func foo(inout bar: [int]) {     var pbar : unsafepointer<int> = unsafepointer(bar)     print("2: \(pbar)")     dispatch_after(dispatch_time(dispatch_time_now, (int64)(2 * nsec_per_sec)), dispatch_get_main_queue()) { () -> void in         pbar = unsafepointer(bar)         print("3: \(pbar)")         bar[0] = 2         pbar = unsafepointer(bar)         print("4: \(pbar)")     } }  var : [int] = [1] var pa : unsafepointer<int> = unsafepointer(a) print("1: \(pa)") foo(&a) print("foo call finished, = \(a)")  dispatch_after(dispatch_time(dispatch_time_now, (int64)(5 * nsec_per_sec)), dispatch_get_main_queue()) { () -> void in     print("value of naturally not changed here = \(a)")     pa = unsafepointer(a)     print("5: \(pa)") }  xcplaygroundpage.currentpage.needsindefiniteexecution = true 

the output quite self-explanatory:

1: 0x00007fe19271e930 2: 0x00007fe19271e930 foo call finished, = [1] <-- call foo finished, 'inout' procedure complete 3: 0x00007fe19271e930           <-- dispatch in `foo` starts 4: 0x00007fe1927085e0           <-- mutates 'bar': 'bar' copied (and never                                      "returned" step finished) value of naturally not changed here = [1] 5: 0x00007fe19271e930           <-- naturally 'a' wont see effect of                                     delayed mutation in foo 

Comments

Popular posts from this blog

php - Wordpress website dashboard page or post editor content is not showing but front end data is showing properly -

javascript - Get parameter of GET request -

javascript - Twitter Bootstrap - how to add some more margin between tooltip popup and element -