2012-02-17 19 views
2

iOSには、描画可能な形状を記述するパスを表す2つのC構造体CGPathRefとCGMutablePathRefがあります。それらの名前から、CGPathRefは修正可能なパスを参照しながら、CGPathRefは一度作成したパスを変更することはできません。しかし、CGPathRefは、CGMutablePathRefを期待する関数に渡すことができます。唯一の違いは、渡された関数がパスを変更した場合に警告が生成され、後者は、 t。たとえば、次のプログラムは: を渡す「CGPathRef」(別名「constの構造体CGPathに*」)型のパラメータ「CGMutablePathRef」(別名「構造体CGPathにする: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によって)参照されているパスを意図していなかったことをプログラマーに思い出させることを除いて、変更?

答えて

3

C言語で間違った型を関数に渡すことは可能ですが、ほとんどの場合必ずしも良い考えではありません。技術的には同じことが定義されているように見えるかもしれませんが、Appleが別のものとして持っている理由はおそらくあります。ほとんどの場合、コードを読みやすく理解しやすくするか、Appleは後で変更を加える予定です。すべてのその後

、定義へのジャンプは、本当の違いを明らかにする:

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

CGPathRefconst typedef(あなたはこれが何をするかは非常にわからない場合は、それをグーグル)です。しかし、Cではconst定義を壊すことができます。なぜなら、CGPathRefCGMutablePathRefを期待する関数に引き渡し、それを正常に変更することができる理由があります。また、なぜそれがdiscards qualifiers警告をスローするかについても説明します。

+0

私は、constポインタを非constのものにキャストすることができることを知っています。しかし、このキャストがApple自身のライブラリ関数内で起こっているように見えるという事実は、私にとってはちょっとファンキーなようでした。エラーはより適切と思われたでしょう)。しかし、私は彼らの定義に照らしてそれ以上のことはないと思う。 – Aky

+0

IMHO、そのようなキャストは、Objective-Cオブジェクトモデルの動的な型付けには不可欠です。 – ZhangChn

+1

ポイントは、**あなたは** constの正確性を維持する必要があります。動作しているように見えても、const修飾されたオブジェクトを変更すると、未定義の動作になります。これは「Apple独自のライブラリの不一致」ではなく、Appleはそれとは関係ありません。メソッドが変更可能であると予想される場合は、変更可能なオブジェクトを渡す必要があります。 –

関連する問題