CGPathRef vs. CGMutablePathRef - PullRequest
       2

CGPathRef vs. CGMutablePathRef

2 голосов
/ 17 февраля 2012

В iOS есть две структуры C, которые обозначают пути, которые описывают прорисовываемые фигуры: CGPathRef и CGMutablePathRef.Из их имен может показаться, что CGPathRef ссылается на путь, который когда-то был создан, не может быть изменен, в то время как CGMutablePathRef ссылается на изменяемый путь.Однако, как выясняется, CGPathRef может быть передан в функцию, которая ожидает CGMutablePathRef, и мне кажется, единственное отличие состоит в том, что первый генерирует предупреждение, если функция, которой он передается, изменяет путь, в то время как последний не 'т.Например, следующая программа:

#import <UIKit/UIKit.h>

@interface TestView : UIView {
    CGPathRef immutablePath;
    CGMutablePathRef mutablePath;
}
@end
@implementation TestView

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        mutablePath = CGPathCreateMutable();
        immutablePath = CGPathCreateCopy(mutablePath); // actually you might just do "immutablePath = CGPathCreateMutable();" here - The compiler doesn't even complain

        self.backgroundColor = [UIColor whiteColor];
    }

    return self;
}


- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    NSLog(@"touchesBegan executed!");
    [self setNeedsDisplay];
}

- (void)drawRect:(CGRect)rect
{
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextAddPath(context, immutablePath);
    CGPathAddRect(immutablePath, NULL, CGRectMake(100.0, 100.0, 200.0, 200.0)); // generates a warning specified later
    CGContextFillPath(context);
}


@end


@interface TestViewController : UIViewController
@end

@implementation TestViewController

@end

@interface AppDelegate : UIResponder <UIApplicationDelegate>

@property (strong, nonatomic) UIWindow *window;

@end

@implementation AppDelegate

@synthesize window = _window;

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    // Override point for customization after application launch.
    self.window.backgroundColor = [UIColor whiteColor];

    // Instantiate view controller:
    TestViewController *vc = [[TestViewController alloc] init];
    vc.view = [[TestView alloc] initWithFrame:[UIScreen mainScreen].bounds];
    self.window.rootViewController = vc;
    [self.window makeKeyAndVisible];
    return YES;
}
@end


int main(int argc, char *argv[])
{
    @autoreleasepool {
        return UIApplicationMain(argc, argv, nil, @"AppDelegate");
    }
}

Это предупреждение от компилятора: Передача 'CGPathRef' (он же const struct CGPath * ') параметру типа' CGMutablePathRef '(он же)'struct CGPath *') отбрасывает квалификаторы

Возможно, я здесь упускаю суть, но есть ли какая-то другая разница между этими двумя, кроме напоминания программисту, что, возможно, он не намеревался использовать путьссылка на которую (CGPathRef) будет изменена?

1 Ответ

3 голосов
/ 17 февраля 2012

В Си можно передать неправильный тип функции, но это почти всегда не очень хорошая идея. Даже если технически они могут быть определены как одно и то же, вероятно, есть веская причина, по которой Apple рассматривает их как отдельные вещи. Скорее всего, это сделает код более читабельным и понятным, или Apple планирует внести изменения позже.

После всего этого, скачок к определению показывает реальные различия:

typedef struct CGPath *CGMutablePathRef;
typedef const struct CGPath *CGPathRef;

CGPathRef - это const typedef (Google, если вы не совсем уверены, что это делает). Однако C позволяет вам нарушать определения const, поэтому вы все еще можете передать CGPathRef в функцию, ожидающую CGMutablePathRef, и точно ее изменить. Это также объясняет, почему оно выдает предупреждение discards qualifiers.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...