wxWidgets using the 'new' keyword - wxwidgets

For wxWidgets, why do you need to say:
MyFrame *frame = new MyFrame
instead of:
MyFrame frame;
What's the difference between the two? The second one is nicer to read and easier to use but all examples use the first so I wondered what the reason is.
Just to clarify, I know the second version doesn't work, but I'm wondering if there's a specific design decision which leads to having to use the first form instead of the second. TIA.

The first allocates a new MyFrame instance on the heap, and returns a pointer to it. The second creates a new MyFrame instance on the stack directly.
The reason you need to use the first syntax is that you will add this frame (UI element) into another UI element, such as a window. The window will take the pointer to a frame, and add it as a child.
If you use the second syntax, you'd have to pass a pointer to your stack object (&frame), which would compile, but then as soon as your method returned, frame's destructor would get called since frame would go out of scope. This would "break" the reference inside of your window.

Related

Does setNeedsDisplay:NO have any use at all?

In Cocoa, when we want to redraw a view, we would send the view a setNeedsDisplay: message telling the view to redraw itself with a parameter of YES. I was wondering if there are any circumstances where you would want to send a view setNeedsDisplay:NO, such as multithreading environments, and if sending a view a setNeedsDisplay:YES, then setting it again immediately after with setNeedsDisplay:NO would make the view redraw itself. If there are no reasons to call setNeedsDisplay:NO, then why create such a tedious method, where they could instead implement something like [view redrawView]
setNeedsDisplay:NO may be used in case you want to discard previously called setNeedsDisplay:YES. E.g. sometimes it is easier to mark all subviews as needing display and then run an algorithm to unmark some of them.
As you perhaps know, the display update is automatic (if necessary) at each pass through the normal event loop. You call setNeedsDisplay: in order to force a display update in between if it is necessary.
From the documentation of NSView:
Discussion
Whenever the data or state used for drawing a view object changes, the view should be sent a setNeedsDisplay: message. NSView objects marked as needing display are automatically redisplayed on each pass through the application’s event loop. (View objects that need to redisplay before the event loop comes around can of course immediately be sent the appropriate display... method.)
The boolean parameter to this function simply specifies if the entire bounds of the view in question is affected or not, not if some property "needsDisplay" is set to true or false. Thus, setNeedsDisplay: does indeed work pretty much like a "redrawView", only with the additional parameter.
Edit
The above was inspired from the same documentation:
flag
If YES, marks the receiver’s entire bounds as needing display; if NO, marks it as not needing display.

Curly Braces in Objective-c

Note: My question is based after checking this and the answers to it.
In some bigger methods, there are pieces of code that you only want to be alive for a certain period of time. An example:
1) I have a big method that sets my UI: UILabel's size, colour, positioning, UIView's gesture recognisers, etc. Knowing the above, does it makes sense to do something like this:
- (void)setUI
{
//setting other UI elements
{
// Add the Swipe Gesture to the swipeUpView
UISwipeGestureRecognizer *swipeGestureUp = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(animeViewWithSwipeGesture)];
swipeGestureUp.direction = UISwipeGestureRecognizerDirectionUp;
[_swipeUpView addGestureRecognizer:swipeGestureUp];
}
// setting other UI elements
}
Based on the above example, is this a valid way of lowering the memory footprint of an application?
Is there any relation with #autoreleasepool{}?
It's just plain C syntax. You use it to open a new scope as others mentioned. What this means (this is C feature) that you can use same names for stack variables again, as they are in different scope. Also, variables you declare inside that scope will not be accessible by outside scope.
There is no relation to memory footprint, only about code organization.
Based on the above example, is this a valid way of lowering the memory footprint of an application?
No. They're not even related. Neither are they related to #autoreleasepool - this usage of curly braces is the plain C way of opening a new scope.
What curly braces do is just to define a new scope, so you can define new variables with the same name than other outer scope variables.
The #autoreleasepool{} block is quiet similar, but also declares an autorelease pool at the beginning and drains it at the end, so it may be better from a memory footprint point of view because all the autoreleased objects declared there will be released when exiting that scope.

How to store CGContext state in a NSMutableArray?

I am new to the CGContext world.
I need to create a stack of CGContext(s) in a NSMutableArray.
I have a valid PDFContext created with UIGraphicsBeginPDFContextToData
I'm passing this context to a method as an argument
-(void) drawTo:(CGContextRef) context{}
First I identify the current context with:
CGContextRef curCon = context;
NSLog value:
context:<CGContext 0x6b79d60>
Then I attempt to make a copy of the current context:
CGContextRef conCopy = UIGraphicsGetCurrentContext();
Then I add it to my NSMutableArray:
[myMutableArray* addObject:(id)conCopy];
Then I list the content of the NSMutableArray:
after an object added:<__NSArrayM 0x6b7e850>(<CGContext 0x6b79d60>)
And I see that the added value is the same context as originally sent to this method as an argument and not the copy.
What am I missing here ? Or perhaps it's not possible to store the status of current context in a NSMutableArray ? I understand that paths would not get saved, that's fine. I need to save anything and everything about the current context that can be saved.
Thank you!
You can't do this directly. But what's the real problem you're trying to solve? CGContextSaveGState() does what you're asking for, but only within the scope of the current context. CGLayer can effectively create contexts that you can carry around (though you still can't serialize them).
If your real goal is to save non-path state in a copyable form, then you can create a copyable object by calling all the CGContextGet... methods and storing their results. Then you can call CGContextSet... on them to make a new context. It's tedious, but should not be difficult. (Though it does raise the question of why. It feels like a very odd thing to be doing.)
UIGraphicsGetCurrentContext does no create a copy. The returned context is there one you created using UIGraphicsBeginPDFContextToData.

Debugging properties in Xcode

So I have a few properties that I'm using in some sample code I'm playing with. Notably the "tag" property of the UIView class. Now I set this property, and if I NSLog it, or setup control statements based on the value of tag, I can see that the value I set is there, and being acted upon as expected.
However, if I hover the mouse over the .tag to see which tag value is there, I get nothing at all from Xcode. No pop up showing the value. So then I go to the auto/local/all window and I try to "Add Expression..." (seems that's the only way to setup a traditional "watch" variable, if there is another way, please let me know). Anyhow so I put my object.tag into the "watch" window and it's blank. No value. It isn't zero it's just nothing, as if it didn't exist.
Of course if I hover the mouse over the "object" part of "object.tag" then I get a pop up for the object with the disclosure triangle, which I expand, then I go looking for "_tag" (which appears to be the underlying instance variable).
So what is so difficult about this? Why isn't the tag property viewable during debug by simply hovering over it? Is this something to do with properties in Xcode dev?
I'm running Xcode 4.3.2
The tag property, as any other Objective-C property, is a syntactic sugar. In fact, properties are implemented as accessor methods, which, in turn, are translated to objc_msgSend() function calls. This machinery is nothing like accessing a struct field.
The debugger can show any field in a struct basically because it doesn't require any special knowledge and doesn't have any consequences. Only the struct definition is needed. Getting the value of an Objective-C property, on the other hand, requires executing code in the process context. You can do that manually in the debugger console, but the debugger just won't do this automatically.
I think this is still theoretically possible in isolated cases, but incredibly hard. Consider a case where executing an accessor method changes the object's internal state. For example, calling -[UIViewController view] (accessing its view property) results in loading the view. There may also be delegate methods called, etc. In such cases hovering the mouse over the property in IDE would alter the execution state of the process and thus make debugging itself a joke.

Passing data to Cocoa Quartz event tap callback - bad casting from void*

I am writing a simple logging program in Cocoa.
I create my callback function to log pressed keys into file, but here comes the problem. I have file handler in my AppDelegate and I can't reach it from inside the callback function.
I tried to pass it inside via last parameter of callback function (the void* one), but inside i have to cast it back to NSFileHandle - but to do that I have to "bridge-cast" it. But whether I use __bridge or __bridge_transfer the program crashes.
I am new to Objective-C so maybe I am missing something obvious, but I had searched "all" the internet, Quartz reference, Stack overflow and googled for few hours so I will appreciate every tip.
Thanks - M
I'm surprised the cast to void * (when you create the tap) is being allowed at all. Isn't the compiler giving you an error on that? The ARC spec says it's verboten.
Having a void pointer be your only strong reference to an object is an anti-pattern. Either that object should be the owner of (in this case) the event tap, or an object should own both the tap and the object that needs to be kept alive. Making the event tap be owned instead of the owner is much more likely to work under all memory-management schemes yet devised, and makes for cleaner code as a side benefit.
(This also goes for NSOpenPanels and NSSavePanels in pre-Blocks code.)