最近我在Cocoa的方法名中看到了“context”这个词,但我不理解其含义。我在Core Data (NSManagedObjectContext
)和Core Graphics (CGBitmapContextCreate
)等地方看到它的应用,但它似乎在许多地方都被使用(NSSet
, NSArray
, NSObject
)。我猜它来自于C语言世界。
他们所说的这个上下文(context)是什么意思?
最近我在Cocoa的方法名中看到了“context”这个词,但我不理解其含义。我在Core Data (NSManagedObjectContext
)和Core Graphics (CGBitmapContextCreate
)等地方看到它的应用,但它似乎在许多地方都被使用(NSSet
, NSArray
, NSObject
)。我猜它来自于C语言世界。
他们所说的这个上下文(context)是什么意思?
这只是术语,你提到的上下文不相关。 上下文 一词通常用于描述特定的“工作空间”。
例如,CGContextRef
或NSGraphicsContext
存储了一个图形空间,您可以在其中执行绘图操作。
NSManagedObjectContext
存储特定持久存储的 NSManagedObjects
的“工作集”。
每个 API 的文档都详细描述了这些上下文的含义。
这句话没有特定的含义,但有两种常见的解释。
第一个解释与数据库、持久化层、图形等需要一些“范围”、“连接”或“状态”的工具有关。例如,在将数据保存到数据库中时,通常需要打开数据库,然后保存一些DB“句柄”,以便在随后的操作中引用。可能会有许多不同的连接,因此可能会有许多不同的“句柄”。换句话说,可能会有许多DB上下文。OpenGL也是如此。
上下文还经常在各种回调和选择器传递API中使用。在这里,它只是当回调发生或选择器被执行时您想要接收的一些数据块。这种情况的常见用例是当您多次订阅并需要区分这些场合时:
// In one part of code not far away.
[anObject subscribeToEvent:NSObjectEventFoo withContext:@"one"];
// Somewhere else.
[anObject subscribeToEvent:NSObjectEventFoo withContext:@"two"];
// And when the callback happens:
- (void) eventFooHappenedInContext: (id) context
{
if ([context isEqual:@"one"]) { /* something */ }
if ([context isEqual:@"two"]) { /* something else */ }
}
上下文还用于排序API,比如你提到的NSArray
。如果你想根据存储在NSDictionary
中的某些权重对对象进行排序,你可以使用上下文来传递权重:
NSInteger weightSort(id obj1, id obj2, void *context)
{
NSDictionary weights = (NSDictionary*) context;
const int weight1 = [[weights objectForKey:obj1] intValue];
const int weight2 = [[weights objectForKey:obj2] intValue];
if (weight1 < weight2)
return NSOrderedAscending;
else if (weight1 > weight2)
return NSOrderedDescending;
else
return NSOrderedSame;
}
这个例子有点牵强,但我想你能理解重点。
我发现有趣的是,上下文很多时候只是语言中缺失闭包的穷人解决方案。因为使用闭包,你可以像在JavaScript中一样传递一个单独的回调处理程序:
anObject.subscribeToEvent(eventFoo, function() { /* do something */ });
anObject.subscribeToEvent(eventFoo, function() { /* do something else */ });
这通常比在回调函数中区分使用案例更优雅。现在,使用Objective-C和blocks可以实现类似于Mike Ash的教程中所示的操作。