How do I set an lldb watchpoint on a property of self.view?

前端 未结 2 2124
一向
一向 2020-12-12 17:26

I want to trace when something changes the size of self.view. What\'s the correct format?

(lldb) po self.view
(UIView *) $1 = 0x0a8aba20 

        
2条回答
  •  北海茫月
    2020-12-12 18:22

    The view controller references its view from its _view instance variable.

    The view doesn't store its frame directly. It just returns its layer's `frame'.

    The view references its layer from its _layer instance variable.

    The layer doesn't store the frame either. It computes its frame from its bounds, position, anchorPoint, and transform. The size is part of bounds.

    The layer doesn't store its bounds directly in an instance variable. Instead, its layer instance variable references an instance of a private C++ class, CA::Layer. The member layout of this class is undocumented.

    In other words, you can go self->_view->_layer->layer to get to the CA::Layer instance, but then you're stuck because you don't know where in the CA::Layer to find the bounds.

    So, trying to use a watchpoint to detect changes to the view's size is rather difficult.

    It is easier to put a breakpoint on -[CALayer setBounds:].

    On the simulator

    Remember to use the layer address in the breakpoint condition, not the view address.

    (lldb) po self.view
    (UIView *) $1 = 0x0a034690 >
    (lldb) break set -F '-[CALayer setBounds:]' -c '((int*)$esp)[1] == 0xa034780'
    Breakpoint created: 2: name = '-[CALayer setBounds:]', locations = 1, resolved = 1
    

    When the breakpoint is hit, the CALayer instance is referenced by ((int *)$esp)[1], and the new bounds is *(CGRect *)($esp+12):

    (lldb) po ((int*)$esp)[1]
    (int) $8 = 167987072 >; sublayers = (); backgroundColor =  [ (kCGColorSpaceDeviceRGB)] ( 1 1 1 1 )>
    (lldb) p *(CGRect*)($esp+12)
    (CGRect) $9 = origin=(x=0, y=0) size=(width=768, height=960)
    (lldb) finish
    (lldb) po 0xa034780
    (int) $10 = 167987072 >; sublayers = (); backgroundColor =  [ (kCGColorSpaceDeviceRGB)] ( 1 1 1 1 )>
    

    On the device

    Remember to use the layer address in the breakpoint condition, not the view address.

    (lldb) po self.view
    (UIView *) $0 = 0x1f031a10 >
    (lldb) break set -F '-[CALayer setBounds:]' -c '$r0 == 0x1f031b00'
    Breakpoint created: 2: name = '-[CALayer setBounds:]', locations = 1, resolved = 1
    

    When the breakpoint is hit, the CALayer instance is referenced by $r0, the new X origin is in $r2, the new Y origin is in $r3, and the new size is *(CGSize *)$sp:

    (lldb) po $r0
    (unsigned int) $7 = 520297216 >; sublayers = (); backgroundColor =  [ (kCGColorSpaceDeviceRGB)] ( 1 1 1 1 )>
    (lldb) p/f $r2
    (unsigned int) $14 = 0
    (lldb) p/f $r3
    (unsigned int) $15 = 0
    (lldb) p *(CGSize *)$sp
    (CGSize) $16 = (width=768, height=960)
    (lldb) finish
    (lldb) po 0x1f031b00
    (int) $17 = 520297216 >; sublayers = (); backgroundColor =  [ (kCGColorSpaceDeviceRGB)] ( 1 1 1 1 )>
    

提交回复
热议问题