what happens to a function bound to last-child when the last child changes? - jquery-selectors

I use the following selector and function:
$("form[name='qc']:last-child").live("focus", newTextLine);
when the :last-child will change, will the .live still be listening to the old :last-child?

live (and delegate) tests the selector when the event happens. If the element is not the last child when it is clicked, the handler won't be executed.
bind (and other methods that use it, such as click), by contrast, tests the selector at the time of the binding, not of the event.

Related

Crash When Accessing refcon:UnsafeMutableRawPointer? Inside CGEventTap Callback

I have a myCGEventCallback function for CGEventTap that takes parameter "refcon:UnsafeMutableRawPointer?".
I pass my main ViewController as a pointer to the callback using
let pointer = UnsafeMutableRawPointer(Unmanaged.passRetained(self).toOpaque())
Then inside the callback, I access the ViewController using
let sender:ViewController = Unmanaged<T>.fromOpaque(refcon!).takeRetainedValue()
When the event occurs, the callback works fine. However, it only works 4 times. When the same event occurs for the fifth time, my app crashes, and the debug console just says "LLDB".
It looks like it crashes when I try to access the sender. "sender.someFunction()". It crashes before the function gets to run, so I assume it has a problem accessing the sender.
Is this because of poor memory management? Maybe I need to deallocate the pointer? If so, how and where would I do that?
Thanks!
passRetained(self) increases the retain count for self (which is your
view controller instance) by one. Each call to takeRetainedValue() decreases
the retain count by one. Those calls must be properly balanced, otherwise
the object might be destroyed too early.
In your case, where the pointer is created once, but used several times in
a callback function, you should use the “unretained” conversion in
the callback:
let sender = Unmanaged<ViewController>.fromOpaque(refcon!).takeUnretainedValue()
so that no ownership is transferred.
There are two patterns how to create the pointer:
If the callback is guaranteed to be active only during the lifetime
of the view controller then you can create the pointer without retaining
the instance:
let pointer = UnsafeMutableRawPointer(Unmanaged.passUnretained(self).toOpaque())
Otherwise, if the view controller instance should be kept alive
while the callback is active, retain it while creating the pointer
let pointer = UnsafeMutableRawPointer(Unmanaged.passRetained(self).toOpaque())
and release it eventually, when the callback is no longer active:
Unmanaged<ViewController>.fromOpaque(pointer).release()

What is the concept of selectors in swift?

I've seen objects which require the parameter, selector. What is the general concept in understanding a selector?
An example of choosing a selector is the NSTimer where my selector I have chosen is a function that increments the counter.
timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: ("incrementCounter"), userInfo: nil, repeats: true)
A selector is a concept from Objective-C that represents a message to be sent (i.e. a method to be called) dynamically at run time. When you set up something to be done via a selector, you know which message will be sent, but not necessarily what its parameters are. (And sometimes not even which object it'll be sent to.)
You can consider selectors a relative of closures/blocks, since they let you package up some code to be called later and hand it off to some other function. However, a closure must be specified/resolved at compile time, so it's less dynamic than a selector.
Selectors are great for "loose binding" concepts like control actions. You can use a selector to choose in Interface Builder which method a button should call when clicked, even though your app isn't actually running in IB; or you can say "this button should call paste: on whatever text view has keyboard focus", not knowing when you set up the button which view that'll be (because keyboard focus changes all the time).
Selectors in ObjC predate blocks/closures, so historically, selectors were the primary way to tell an API things like "call this method later", which is why you find them throughout Cocoa for patterns like timers, array sorting, and undo even when such patterns might benefit more from the tight binding of closures/blocks.
For more on using selectors in Swift, see Interacting with Objective-C APIs in Using Swift with Cocoa and Objective-C and/or this SO answer. For more on selectors and Cocoa in general, see Cocoa Core Competencies: Selector.
A selector is a custom method which is called in the class specified by target when the timer fires. If the method is supposed to take parameters each parameter is represented by a colon.
In Swift the struct Selector responds to the protocol StringLiteralConvertible,
Therefore – since the compiler knows the type in your example – a literal string is implicitly converted to a Selector instance and the Selector initializer is not needed.
PS: The parentheses around your selector string are not needed either.

How can I avoid this "variable used within its own initial value" error?

Update:
This is an attempt to improve this question. I have a solution, which I will post as an answer shortly. Its based on the comments I received below. Hopefully this improvement, along with the comments and subsequent answer, can help someone else who might fall into the same trap I did.
I have a collection of objects that need to download some images before I consider them "ready".
I attempted to handle this by passing in a "completion handler" into the init function, which I in turn would pass it to the completion handler of the function that would actually download the images. The intended net result being that after the object was initialized and loaded with it's images, then the closure I passed in during initialization would be called, in this case a notification that the object was "ready"
To accomplish this I tried to capture the newly created object in the closure passed in as the completion handler. (shown below in trailing closure format)
for marker in markerList {
var ourLatitudeMapMarker = OurLatitudeMapMarker(size: size) {
NSNotificationCenter.defaultCenter().postNotificationName("OurLatitudeMapMarkerReady", object: self, userInfo: ["ourLatitudeMapMarker":ourLatitudeMapMarker])
}
}
This results in the error "variable used within its own initial value".
My original, poorly phrased question, was essentially:
How can I get the newly created object into the completion handler passed to the init function so that it can be used in the completion handler when the object finally, is "ready"
In hindsight I think my question should have been:
How can I call a closure when my objects are "ready"? "ready" being initialized and loaded with their images.
As jtbandes pointed out in his comment, one solution to this could have been to simply pass self in as an argument to the the completion handler, but in the end I agreed with both nhgrif's and zaph's comments.
The solution was obvious, once I realized that being initialized and being ready are not the same thing. So I just have init, initialize the object and another method loadImages, takes the completion handler, which is passes to the method that actually down loads the images, and calls the completion handler when the objects are ready.
So now instead of one statement that attempted to do everything (initialize and load the images), I have two.
let ourLatitudeMapMarker = OurLatitudeMapMarker(size: size)
and then later do something like this
ourLatitudeMapMarker.loadImages() {
NSNotificationCenter.defaultCenter().postNotificationName("OurLatitudeMapMarkerReady", object: self, userInfo: ["ourLatitudeMapMarker":ourLatitudeMapMarker])
}

Is it possible to schedule multiple selectors or update callbacks on single CCNode object

I am using cocos2d 2.0
in my layer class I am scheduling a method
[self schedule:#selector(myMethod:) ];
then in the same layer I scheduling another method like this
[[self scheduler]scheduleSelector:#selector(mySecondMethod) forTarget:self interval:enemySpawnSpeed paused:NO];
When I run the code it says 'CCScheduler. Trying to schedule a selector with a pause value different than the target'
when I comment any one of these lines my project runs ok and give no errors. Is it impossible to schedule multiple selectors with a same node ? or am I doing something wrong here ?
after reading the guide http://www.cocos2d-iphone.org/wiki/doku.php/prog_guide:draw_update I am not sure but I think we can only schedule one selector per node
Sure, this works:
[self scheduleSelector:#selector(myMethod:)];
[self scheduleSelector:#selector(mySecondMethod:)];
Your mySecondMethod selector was missing a colon at the end. The error you got was related to the paused flag, you should have used self.paused instead of using NO to ensure the selector's paused state is the same as the target's.
Also that second line is odd, did you try to schedule updates from outside the class? If so, simply send a message to the layer object (ie scheduleMySecondMethod) that then schedules the selector.

Boolean variable that evaluates whether or not the current view has disappeared?

I am using an NSTimer that runs down from 15 seconds in a multiple choice quiz app. The app has two possible outcomes. The time may run down to zero, and the incorrectAnswer view is shown, in which case the Timer is invalidated/stopped and the static integer for its time is reset back to 15 for the next question.
However, the other possible outcome is that an answer is selected before time runs down, in which case I use the method viewWillDisappear to trigger further action. My problem is that I cannot reset the static integer for time from this method, because it is declared in the method above. I tried declaring it in the .h file, but there are problems because the integer is static.
I want to know if there is a boolean expression that evaluates if the current view has disappeared, because this way I can keep everything in the same method and be able to reset the static integer for time.
First, if your timer variable local to the class, it doesn't have to be declared as static. Secondly, you have two opportunities to address your problem from the viewController: viewWillDisappear and viewDidDisappear. Lastly, if you need to know if a view property has changed, you can do it via a KVO method. The problem you'll run into is if the view has truly disappeared, the view object may be toast by the time you reference it. Without more info, there is no way to tell what problem you're truly having.
Also, once you invalidate a timer, you can no longer use it. You must create a new timer.