如果您在拥有图形上下文之前尝试在图形上下文中或对图形上下文执行操作,则可能会发生这种情况。
您可以在 OS X 上看到相同的内容。
确保您的视图实际上位于窗口中的视图层次结构中。
Core Graphics / Quartz,不会为您提供没有窗口的图形上下文。
在 iOS 上只有一个窗口。
UIView 的子类可以使用 viewDidMoveToWindow 或 viewDidMoveToSuperview 作为检查窗口是否为 nil 和 superview 是否为 nil 的好时机。
这告诉您应该可以获得有效的上下文。
NSView 也有类似的方法可以覆盖。
我有。尽管如此,在 OS X 上看到的 Apple 应用程序也会向控制台发送相同的消息,因此如果它是由 Apple 框架代码发出的,您可能无法对其进行任何处理,除非提交错误。
在这种情况下,init 会给你一个 UIVIew,但它不是指定的初始化程序 initWithFrame: 和 OS X 上的 NSView 相同。所以你的视图没有框架,也没有坐标空间。因此,当您没有有效上下文时,有时会调用需要有效图形上下文的代码。它可能是您的代码,也可能是框架代码。一些未记录的事情发生在未记录的订单中。通常,如果您使用推荐的方法并按正确的顺序做事,则无需担心。
因此,在尝试执行任何需要有效 CGContext 的操作之前,您需要设置框架属性。当你尝试改变它时,你还需要确保你有一个有效的 CGContext。
错误说 CGContextSetCTM 这是一个 CGContext 函数,用于在图形上下文上设置转换。使用 CGContextGetCTM 很容易做到这一点。如果传入的上下文无效,则会出现此错误。所以,问题是,这是你的代码吗?还是别人的?
在 UIViewController 子类中考虑以下内容
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.aView = [[UIView alloc] init];
// self.aView.frame = CGRectMake(0, 0, 30, 30);
// Uncomment the above line and your error will go away. Not because you set a size greater than zero, but because you set an origin point and a size for the frame.
// Set the frame after the view is in the window view hierarchy and the error will stop occurring.
self.aView.backgroundColor = [UIColor redColor];
[self.view addSubview:self.aView];
CGContextRef context = UIGraphicsGetCurrentContext();
// This context is actually NULL.
CGAffineTransform CTM = CGContextGetCTM(context);
// Above line will give you a nice similar error. (get instead of set)
[self.view setNeedsDisplay];
}
我们不知道操作是否使用自动布局。没有发布足够的代码。
如果添加可满足的 NSLayoutConstraints,Autolayout 系统将创建原点,从而可以创建有效的 CGContext。
但问题的关键是必须在上下文可以访问或修改之前设置源点和大小,因为没有它,你有一个 NULL CGContext。
使用自动布局,必须在访问或修改上下文之前添加约束。
对于手动布局框架,必须在访问或修改上下文之前设置框架(零矩形或其他)。
指定初始化器要求它的原因是因为它是确保 CGContext 为 NULL 时没有任何东西击中的最安全时间。
您绝对可以在 initWithFrame: 中将 CGZeroRect 设置为您的框架,并且您应该使用 Autolayout。
你绝对仍然可以使用 init 来代替,尽管没有记录,只要你在任何东西到达你的 CGContext 之前设置一个框架或添加约束。
它没有记录,所以它是有风险的。
您应该始终使用 initWithFrame: 如果您不使用 xib/nib/storyboard(那些将从 initWithCoder 中的 xib/nib/storyboard 获取框架:)
最好的建议仍然是使用指定的初始化器,但事实是,在视图移动到有效窗口中的有效视图层次结构之前,CGContext 不能实际存在,因为上下文是从父视图上下文中派生的窗口中的有效层次结构。