Has anyone got an NSOperationQueue class for iOS yet. I am wanting to use it with accelerometer events and I’m not schooled enough in declares yet to make sense of how to set it up. It looks doable, but I’m not sure what to make of the reference. I think I mainly need one function.
Returns the operation queue associated with the main thread.
- (NSOperationQueue *)mainQueue
Does this mean I need to create a shared method in Xojo and it will return a ptr to an instance of my class.
What are you really trying to accomplish? The docs on CMMotionManager say
Because the processed events might arrive at a high rate, using the main operation queue is not recommended.
So setting it up to receive updates on the main queue might not be the best approach.
As a side note - are you using iOSKit? I included several of the classes to handle the motion (acceleration, gyro, etc) of the device, and the properties update quickly enough that you can poll them with a timer just fine at whatever your desired rate is. There is an example view included with iOSKit that demonstrates this.
If you really want to use that method, the necessary declares are:
declare function NSClassFromString lib "Foundation.framework" (clsName as CFStringRef) as ptr
declare function mainQueue lib "Foundation.framework" selector "mainQueue" (clsRef as ptr) as ptr
dim theMainQueue as ptr = mainQueue(NSClassFromString("NSOperationQueue"))
and you can pass the ptr to whatever declare needs an NSOperationQueue.
On the other hand, Xojo and non-main dispatch queues don’t really go together. It’s the same as running Xojo code in a non-Xojo thread.
Yes I know. But many of the classes provide mechanisms so that you can poll them without needing callbacks which could be better depending on what he is doing. I was merely stating that it might be better to poll with a timer at the desired interval than overrun the main thread with unnecessary callbacks which could slow down the application.
I’ve seen various examples, and I got the impression that if I wanted timely sampling the NSOperationQueue was the recommended approach. Maybe it’s not needed, but I guess I won’t know for sure which works better unless I try them both. The other thing I was concerned with is what happens when the app goes to the background. Seems like the NSOperationQueue would let the events queue up to be handled when possible whereas a timer might not fire. It’s all speculation right now since I don’t have it working yet, and I’m really just starting to try Xojo for iOS stuff.
If anyone has some concrete advice that might save me some time and effort going down the wrong path I’d appreciate it.
if you want to try without having to set up all on our own, I have a basic implementation of NSOperationQueue in my iOSLib. Currently it addresses the main queue only I needed this for the Notification Center , but it wouldn’t be that much to add other methods for testing. I wasn’t sure if more would be needed for iOS, but I’d welcome the information you get from experimenting with it. If you need help setting up methods for it, just tell me what you are missing.
I thought I looked in iOSLib, maybe I didn’t. I’ll check it out. Thanks Ulrich.
Theres still loads of documentation missing, and this class being there for the sake of just one other still undocumented class is one of them
I found the implementation in iOSLib. I’m curious though why it uses UIKit framework instead of Foundation. Looking at the docs online I expected to see foundation and not UIKit. Is it common to see helper classes like this in multiple frameworks? Sorry if this is a basic question. I’m not that familiar with how all the frameworks are supposed to fit together. I always thought of them as a group of functionality typically pertaining to one type of broad feature or related features.
A lot of the symbols from Foundation are re-exported by other frameworks so UIKit will work in this case. It’s safer to use the explicit framework, but since it is re-exported its fine to use UIKit. It’s the same reason you can use “Cocoa” for many frameworks on OSX.
I wouldn’t rely on re-exports.
Yes, you’re right, I wouldn’t too
Reason this class is imported from UIKit is I didn’t check the framework. Probably should change the reference of all NSObject subtypes to Foundation. Thanks for the hint!
EDIT: @Kevin, I updated a few properties but did not upp the project because it looks to me there is little use for this class as long as no NSOperation class exists too. And while the latter one knows a completion block for easy event handling the implementation of the main method if it should work at all would have to be done by overriding the instance’s main method. This is all possible, but currently I am already tired when I wake up and find this task a bit too demanding. Will look into it when it’s easier to keep my eyes open.
No worries Ulrich, I think I have the basics working for my usage. The mainQueue is all I needed and I think I have that part working.
On a maybe unrelated note, I’m not sure I understand the full ramifications of using this the way I am currently doing.
My app tends to crash quite a bit. It seems to only happen on the second or third attempt at getting accelerometer updates, and judging by the crash log it appears to be memory management related.
I am allocating an iOSBlock and assigning it the address of a function. I pass the handle of the block and the handle of the mainQueue into the startAccelerometerUpdatesToQueueWithHandler declare and that seems to work. After doing this two or three times in a run of the app I get a crash.
The crashes all are either in RuntimeLockObject or RuntimeUnlockObject.
What are the best practices for an iOSBlock. Should I only allocate one and hold it in a property. I guess I was thinking it wouldn’t matter either way since presumably it’s referencing the same function every time I create it, but maybe that’s not only inefficient, but a memory management issue.
Just now tried holding the reference and it seems to behave now. Sometimes just the act of typing forum posts leads to answers.
I’m not sure I fully understand what you are doing, but you should only have to call the start function once (unless you then stop it). Are you calling the start function more than once?
Also, I have found that code running in blocks can be a bit flakey/unstable with random crashes. Maybe you can post the code you have running in the iosblock? What I have been doing is retaining the returned objects in the block and setting a boolean flag that the block was called. I then have a method that watches this flag using Xojo.core.timer.CallLater and when it changes does processing and releases the retained objects. This seems to eliminate the random crashes but might not work well in your situation since you have the block called continuously. Also posting a more complete crash report will help to better diagnose the problem.
Yes, the app allows the user to start and stop the logging of the sensor data. Starting and stopping several times would create the crash.
The code in the iosblock is simply updating text on some labels using the accelerometer data passed in to the block. I have not been able to cause a crash since storing and reusing my block reference. So while I don’t know the specific cause it does seem likely that reallocating the block was leading to the crash somehow.