有没有可能使用NSLog输出C结构体(例如CGRect或CGPoint)?

417
我希望能够调试 C 结构体时,无需逐个输入其所有属性。
例如,我想要做到这样:
CGPoint cgPoint = CGPointMake(0,0);
NSLog(@"%@",cgPoint);

显然 '%@' 不起作用,这也是问题的原因。


2
NSLog(@"%@", CGRectCreateDictionaryRepresentation(rect)); NSLog(@"%@", CGRectCreateDictionaryRepresentation(rect)); - Abhishek Bedi
尝试使用VTPG_Common库中的LOG_EXPR:http://vgable.com/blog/tag/log_expr/ - CodeSmile
9个回答

806

你可以尝试这个:

NSLog(@"%@", NSStringFromCGPoint(cgPoint));

UIKit提供了许多函数,用于将不同的CG结构体转换为NSString它不能正常工作的原因是%@表示一个对象,而CGPoint是一个C结构体(CGRectCGSize也是结构体)。


7
在 macOS 上使用 AppKit,您需要将点坐标转换为 NSPoint 类型,然后调用 NSStringFromPoint 方法。例如:NSStringFromPoint(NSPointFromCGPoint(point)) - Alex
19
NSLog(@"%@", CGRectCreateDictionaryRepresentation(rect));翻译:打印出CGRectCreateDictionaryRepresentation函数对矩形rect所创建的字典表示。 - Abhishek Bedi
类似于 UI、MK、CL 前缀,它们都有各自的含义,并需要导入相应的 .h 文件,如:UIKit、MapKit、CoreLocation;那么 CG 前缀是否意味着我需要导入任何东西?如果不是,那它只是一种命名约定吗?! - mfaani

236

有一些函数,例如:

NSStringFromCGPoint  
NSStringFromCGSize  
NSStringFromCGRect  
NSStringFromCGAffineTransform  
NSStringFromUIEdgeInsets
一个例子:
NSLog(@"rect1: %@", NSStringFromCGRect(rect1));

4
这就是iOS开发中最有用但鲜为人知的“单个事物”!!嘿 - Fattie
8
注意:针对Cocoa(OS X)开发,这些函数的名称中不含有“CG”。 - peterflynn

18
NSLog(@"%@", CGRectCreateDictionaryRepresentation(rect));

13
我使用以下宏来帮助我处理NSRect:
#define LogRect(RECT) NSLog(@"%s: (%0.0f, %0.0f) %0.0f x %0.0f",
    #RECT, RECT.origin.x, RECT.origin.y, RECT.size.width, RECT.size.height)

您可以对 CGPoint 进行类似的操作:

@define LogCGPoint(POINT) NSLog(@"%s: (%0.0f, %0.0f)",
    #POINT POINT.x, POINT.y);

使用方式如下:

LogCGPoint(cgPoint);

将产生以下结果:

cgPoint: (100, 200)

6
为什么不直接使用内置的UIKit字符串转换函数 - ma11hew28
我现在明白了。那些正是Alex和Steve在他们的答案中发布的函数。 - e.James
1
是否值得编辑答案并在顶部添加一个注释“仅供历史参考...”?我总是这样做,例如https://dev59.com/13VD5IYBdhLWcg3wXaid#2530953 https://dev59.com/QlXTa4cB1Zd3GeqP4b2c#5492892 https://dev59.com/eVHTa4cB1Zd3GeqPWPv9#4212826(*“值得注意的是,这篇文章来自上个十年,现在只有历史意义。”*)等。 - Fattie
1
尽管存在UIKit转换函数,但这个答案仍然有用,因为其他框架中还有其他结构体没有NSStringFrom助手(例如MKCoordinateRegion)。 - Greg Bell

10
您可以使用NSValue来实现。一个NSValue对象是一个简单的容器,用于存储单个的C或Objective-C数据项。它可以包含任何标量类型,例如int、float和char,以及指针、结构体和对象ID。 示例:
  CGPoint cgPoint = CGPointMake(10,30);
    NSLog(@"%@",[NSValue valueWithCGPoint:cgPoint]);

输出:NSPoint: {10, 30}

希望能对你有所帮助。


6

是的,您可以使用以下几个函数: 首先,您需要将CGPoint结构转换为字符串,例如:

1) NSStringFromCGPoint,  
2) NSStringFromCGSize,  
3) NSStringFromCGRect,  
4) NSStringFromCGAffineTransform,  
5) NSStringFromUIEdgeInsets,

例如:

1) NSLog(@"NSStringFromCGPoint = %@", NSStringFromCGRect(cgPointValue));

Like this...


5

由于 Stack Overflow 的 RSS 出了问题,这个问题又被我找回来了,所以我提供一个几乎通用的解决方案:JAValueToString

使用它,你可以写 JA_DUMP(cgPoint),然后得到 cgPoint = {0, 0} 的日志。


我做了那个,但是出现了编译错误。有时需要属性表达式的地址或其他东西。 - user4951
@Jim Thio:宏的设置是这样的,被检查的对象必须是一个左值。(我记不清为什么了;大概是因为不能正确处理C字符串。)简而言之,将您的属性分配给一个临时变量,然后对该变量调用JA_DUMP。 - Jens Ayton

2
NSLog(@"%@",CGRectCreateDictionaryRepresentation(rect));

0
使用 Objective-C 的方式从 C 原始类型创建对象。
CGRect rect = CGRectMake(1, 2, 3, 4);
CGSize size = CGSizeMake(1, 2);
NSLog(@"%@, %@",@(rect), @(size));

输出:NSRect: {{1, 2}, {3, 4}}, NSSize: {1, 2}


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接