So i was reading Mike Ash's article on Swift speed where i encountered that if we have an empty function then a method call will not be made by Swift
func test() {}
Then a call to test() basically would not be called by the compiler.
Now if i remember correctly then Apple recommends against leaving an empty drawRect: method because it might hinder performance.
Now my question is if an empty function is never called by the compiler then why against the empty drawRect:
I was just curious. Thanks
The problem with drawRect is not the function call. You can't just call drawRect, there is a lot of setup needed to set up the correct context for drawRect. And the code doing that setup can check that there is no drawRect method and avoid the whole setup, but it cannot detect that drawRect does nothing.
Related
How Can i Call
-(void)drawRect:(CGRect)rect
in https://github.com/stkim1/MTImageMapView/blob/master/MTImageMapView/MTImageMapView.m
From Another UiViewController Periodically With NSTimer
From the documentation:
Discussion
The default implementation of this method does nothing. Subclasses
that use technologies such as Core Graphics and UIKit to draw their
view’s content should override this method and implement their drawing
code there. You do not need to override this method if your view sets
its content in other ways. For example, you do not need to override
this method if your view just displays a background color or if your
view sets its content directly using the underlying layer object.
...
If you subclass UIView directly, your implementation of this method
does not need to call super. However, if you are subclassing a
different view class, you should call super at some point in your
implementation.
This method is called when a view is first displayed or when an event
occurs that invalidates a visible part of the view. You should never
call this method directly yourself. To invalidate part of your view,
and thus cause that portion to be redrawn, call the setNeedsDisplay or
setNeedsDisplayInRect: method instead.
YES i Found The solution i am calling a function with timer at the End of a drawrect function and calling setNeedsDisplay()in it
I want to dynamically change the current CGContextRef according to different user actions? Is this possible or is its modification only possible within drawRect: of a view instance? What happens when I call UIGraphicsGetCurrentContext() outside drawRect: and are there any limitations in doing so, is this recommended? Any possible implications I need to consider?
According to the docs the graphics context is only set just before this function is called. This means that if this function is not called it won't be set and if you don't make the system call it again (never do this yourself for that reason) it won't be there either.
Use one of these functions to force the view back into drawRect:
setNeedsDisplay:
setNeedsDisplayInRect:
It doesn't mean you can only do stuff inside drawRect however. This context is sort of globally available at that moment and you can call clean separate functions or even classes for drawing things. Passing the reference to those functions is a clean way to do it.
I was wondering if I can call willMoveToSuperview on UIView and after that retain that view to reuse later for one ? something like following
if (!CGRectIntersectsRect(cell.frame, visibleRegion)) {
[cell willMoveToSuperview:nil];
[self.resuableCells addObject:cell];
}
I am not sure about your intent here...
But WillMoveToSuperview - According to doc:
The default implementation of this method does nothing. Subclasses can override it to perform additional actions whenever the superview changes.
So your code,
[cell willMoveToSuperview:nil];
Has no effect unless you override this method in a cell subclass and implement your own logic there.
Coming to your question -
Does willMoveToSuperview will also deallocate the UIView on which its got called?
Answer is obvious - NO.
willMoveToSuperview is an observer method that the system calls as a courtesy to you in order to give you a chance to handle special cases before it completes some other hidden tasks.
It's default behavior is to do nothing, but you might want to tidy up something in your code prior to a move by overriding this method.
A proper use case might be if you had a view playing a video clip or an animation, and something else in your code is about to rip the view out of it's current hierarchy and place it in some other un-related view hierarchy. You might want the chance to pause the clip or suspend the animation before the move took place.
I doubt it's the right method to handle what you are attempting, and I definitely know you should not be calling it directly.
Feel free to post some more code to show us what you're trying to accomplish and where it's going wrong.
I found this in the Quartz 2D Programming Guide:
To draw to the screen in an iOS application, you set up a UIView object and implement its drawRect: method to perform drawing. The view’s drawRect: method is called when the view is visible onscreen and its contents need updating. Before calling your custom drawRect: method, the view object automatically configures its drawing environment so that your code can start drawing immediately. As part of this configuration, the UIView object creates a graphics context (a CGContextRef opaque type) for the current drawing environment. You obtain this graphics context in your drawRect: method by calling the UIKit function UIGraphicsGetCurrentContext.
Since I am having problems with invalid Context (because it's 0x00 when I go back to re-draw), I was wondering if I could get the current context in the beginning of -drawRect and somehow pass it to the methods I call from within -drawRect?
You can definitely pass CGContextRef to methods called from drawRect: as long as these methods do not save the reference for use outside the duration of the drawRect: call, your code should be fine. However, the context reference that you pass around would be equivalent to the context retrieved through UIGraphicsGetCurrentContext, so I doubt that there is much to gain by adding an extra parameter.
UIGraphicsGetCurrentContext can only be called from drawRect: method (or methods called from it) otherwise it will return nil.
You can use UIGraphicsGetCurrentContext from any method called from -drawRect. It's worth noting that you should not call -drawRect directly when you need to update your view; call -setNeedsDisplay instead.
If you want to use the UIKit drawing system with your own off-screen context, you can use UIGraphicsPushContext to set the current context.
In my experience, passing CGContextRef produces a memory leak that's pretty "fast."
I'm using a container UIView to house a UIImageView and do some custom drawing. At this point I'd like to do some drawing on top of my subview. So overriding drawRect: in my container UIView will only draw below the subviews.
Is there a way to overload drawRect: in my subview without subclassing it?
I think method swizzling may be the answer, but I'm hoping not.
(NOTE: yes, it would have been smarter to have the UIView be the subview of the UIImageView, but unfortunately I'm committed to my mistake now.)
Are you sure you mean overload and not override?
Overloading -- creating a new method with the same basic name but different arguments and therefore a different selector -- could be accomplished by adding a new method category containing your new method to the existing class.
Overriding -- modifying the behavior of an existing method -- would require either monkey-patching the class's method table at runtime (for example, by swizzling) or subclassing.