简体   繁体   中英

Objective-C Inheritence of iVar

In Route-Me from MapBox I've seen iVars implemented like this:

@implementation RMMapView
{
    BOOL _delegateHasBeforeMapMove;
    BOOL _delegateHasAfterMapMove;
    BOOL _delegateHasBeforeMapZoom;
    BOOL _delegateHasAfterMapZoom;
    BOOL _delegateHasMapViewRegionDidChange;
    BOOL _delegateHasDoubleTapOnMap;
    BOOL _delegateHasSingleTapOnMap;
    BOOL _delegateHasSingleTapTwoFingersOnMap;
    BOOL _delegateHasLongSingleTapOnMap;
    BOOL _delegateHasTapOnAnnotation;
    BOOL _delegateHasDoubleTapOnAnnotation;
    BOOL _delegateHasTapOnLabelForAnnotation;
    BOOL _delegateHasDoubleTapOnLabelForAnnotation;
    BOOL _delegateHasShouldDragMarker;
    BOOL _delegateHasDidDragMarker;
    BOOL _delegateHasDidEndDragMarker;
    BOOL _delegateHasLayerForAnnotation;
    BOOL _delegateHasWillHideLayerForAnnotation;
    BOOL _delegateHasDidHideLayerForAnnotation;

    BOOL _constrainMovement;
    RMProjectedRect _constrainingProjectedBounds;

    float _lastZoom;
    CGPoint _lastContentOffset, _accumulatedDelta;
    BOOL _mapScrollViewIsZooming;
}

That is, it's declared in the .m files instead of the .h files. If I sub-class this RMMapView, I don't see these iVars. Is there a way to make it visible in subclass while not to the world?

It's my intention to preserve the original code so chose to sub-class and modify the behavior from there. But perhaps just change the files directly and update codes from the main repostory via git is a better way to do it?

In Objective-C (as in other OO languages) most developers consider instance variables an implementation detail of the defining class. They should not be accessed directly by other classes.

In this case the instance variables are declared in the implementation which is a strong hint that the authors of RMMapView don't want to expose the variables to outside code.

If you really want instance variables visible to subclasses, you need to declare them in the @interface , not the @implementation .

@interface RMMapView : NSObject
{
@protected
    BOOL _delegateHasBeforeMapMove;
    BOOL _delegateHasAfterMapMove;
    BOOL _delegateHasBeforeMapZoom;
    BOOL _delegateHasAfterMapZoom;
    BOOL _delegateHasMapViewRegionDidChange;
    BOOL _delegateHasDoubleTapOnMap;
    BOOL _delegateHasSingleTapOnMap;
    BOOL _delegateHasSingleTapTwoFingersOnMap;
    BOOL _delegateHasLongSingleTapOnMap;
    BOOL _delegateHasTapOnAnnotation;
    BOOL _delegateHasDoubleTapOnAnnotation;
    BOOL _delegateHasTapOnLabelForAnnotation;
    BOOL _delegateHasDoubleTapOnLabelForAnnotation;
    BOOL _delegateHasShouldDragMarker;
    BOOL _delegateHasDidDragMarker;
    BOOL _delegateHasDidEndDragMarker;
    BOOL _delegateHasLayerForAnnotation;
    BOOL _delegateHasWillHideLayerForAnnotation;
    BOOL _delegateHasDidHideLayerForAnnotation;

    BOOL _constrainMovement;
    RMProjectedRect _constrainingProjectedBounds;

    float _lastZoom;
    CGPoint _lastContentOffset, _accumulatedDelta;
    BOOL _mapScrollViewIsZooming;
}

The @protected at the top qualifies the visibility, it can also be @public or @private . @protected is the default but it's better to put it in explicitly to show you deliberately want these ivars to be visible to subclasses.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM