Obj-C:在@implementation块内部或外部声明的C函数,有什么区别?

jlp*_*ita 7 c cocoa-touch objective-c

在Objective-C类的实现块(@implementation ... @end)内部或外部声明的C函数(静态或非静态)之间的区别是什么?

这是特别真实的吗?:

如果需要直接在对象内部进行戳,可以将此函数放在类的@implementation块中,然后可以使用C箭头运算符访问实例变量.但这有点顽皮,所以为了保持你的精华纯度,你应该在对象上使用方法调用.结束讲道.这是邪恶的:

@implementation OblateSphereoid

void drawEggThunk (DrawingContext *context, Rect areaToDraw, void *userData)
{
BWOblateSphereoid *dealie = (BWOblateSphereoid *)userData;
dealie->_frognatz = [NSColor plaidColor];
// and more stuff.
} // drawEggThunk

...
@end // OblateSphereoid
Run Code Online (Sandbox Code Playgroud)

我能以这种方式访问​​函数中的类的实例变量(在同一个类中声明)吗?

Rob*_*ier 2

虽然这是合法的,但我不明白为什么在您所描述的情况下需要它(这是一个丑陋的解决方案)。为什么你不能直接调用:

[dealie setFrognatz:[NSColor plaidColor]];
Run Code Online (Sandbox Code Playgroud)

如果您通常不提供 a -setFrognatz:,只需将其声明为私有方法即可,方法是在 .m 内但在此函数定义之上声明它。(在这种情况下,它是否在块中实际上并不重要@implementation。)

@interface BWOblateSphereoid ()
- (void)setFrognatz:(NSColor *)acolor
@end

@implementation OblateSphereoid

void drawEggThunk (DrawingContext *context, Rect areaToDraw, void *userData)
{
    BWOblateSphereoid *dealie = (BWOblateSphereoid *)userData;
    [dealie setFrognatz:[NSColor plaidColor]];
    // and more stuff.
} // drawEggThunk

...
@end // OblateSphereoid
Run Code Online (Sandbox Code Playgroud)

在一些地方,->符号会很有帮助。最关键的是在绝对需要的-copyWithZone:地方实现它(这个要求真正强调了为什么我讨厌任何像这样使用原始内存的 ObjC 代码)。但我在大多数情况下建议不要这样做,原因与我总是推荐访问器的原因相同。即使在您需要通过引用 C 函数( 的另一种常见用法)传递 ivar 的情况下,我更喜欢使用临时变量,然后再对其进行分配。NSCopyObject()->->

我认为 ivar 默认情况@private下并不是 ObjC 中的错误……我将其放在@private每个块的顶部@interface,并通过这种方式避免了几个令人讨厌的错误。

顺便说一句,您所写的解决方案可能会泄漏NSColor. 也许是,也许不是,但访问器是确定的。