iCloud之旅
1、创建BIDTinyPixDocument类
#import <UIKit/UIKit.h> //创建文档类
@interface TinyPixDocument : UIDocument
//接收一对行和列索引作为参数
- (BOOL)stateAtRow:(NSUInteger)row column:(NSUInteger)column;
//指定的行和列设置特定的状态
- (void)setState:(BOOL)state atRow:(NSUInteger)row column:(NSUInteger)column;
//负责切换特定位置处的状态
- (void)toggleStateAtRow:(NSUInteger)row column:(NSUInteger)column; @end
#import "TinyPixDocument.h" //类扩展
@interface TinyPixDocument ()
@property (nonatomic,strong) NSMutableData * bitmap;
@end @implementation TinyPixDocument //将每个位图初始化为从一个角延伸到另一个角的对角线图案。
- (id)initWithFileURL:(NSURL *)url
{
self = [super initWithFileURL:url];
if (self) {
unsigned char startPattern[] = {
0x01,
0x02,
0x04,
0x08,
0x10,
0x20,
0x40,
0x80
}; self.bitmap = [NSMutableData dataWithBytes:startPattern length:];
}
return self;
} //实现读取单个位的状态的方法。实现这个方法只要从字节数组中获取相关字节,然后对其进行位移操作和AND操作,检查是否设置了给定位,相应的返回YES或NO。
- (BOOL)stateAtRow:(NSUInteger)row column:(NSUInteger)column
{
const char * bitmapBytes = [self.bitmap bytes];
char rowByte = bitmapBytes[row];
char result = ( << column) & rowByte;
if (result != ) {
return YES;
} else {
return NO;
}
}
//这个方法正好和上一个相反,用于为给定行和列的位置设置值。
- (void)setState:(BOOL)state atRow:(NSUInteger)row column:(NSUInteger)column
{
char *bitmapBytes = [self.bitmap mutableBytes];
char *rowByte = &bitmapBytes[row]; if (state) {
*rowByte = *rowByte | ( << column);
} else {
*rowByte = *rowByte & ~( << column);
}
}
//辅助方法,外部代码使用该方法来切换单个单元的状态。
- (void)toggleStateAtRow:(NSUInteger)row column:(NSUInteger)column
{
BOOL state = [self stateAtRow:row column:column];
[self setState:!state atRow:row column:column];
} //保存文档时调用
- (id)contentsForType:(NSString *)typeName error:(NSError **)outError
{
NSLog(@"saving document to URL %@", self.fileURL);
return [self.bitmap copy];
}
//系统从存储区加载了数据,并且准备将这个数据提供给文档类的一个实例时,调用此方法。
- (BOOL)loadFromContents:(id)contents ofType:(NSString *)typeName
error:(NSError **)outError
{
NSLog(@"loading document from URL %@", self.fileURL);
self.bitmap = [contents mutableCopy];
return true;
}
2、主控制器代码
#import "BIDMasterViewController.h"
#import "BIDDetailViewController.h"
#import "BIDTinyPixDocument.h" @interface BIDMasterViewController () <UIAlertViewDelegate> @property (weak, nonatomic) IBOutlet UISegmentedControl *colorControl;
@property (strong, nonatomic) NSArray * documentFilenames;
@property (strong, nonatomic) BIDTinyPixDocument * chosenDocument; @property (strong, nonatomic) NSMetadataQuery * query;
@property (strong, nonatomic) NSMutableArray * documentURLs; @end @implementation BIDMasterViewController /* original
//接收一个文件名作为参数,将它和应用的Document目录的文件路径结合起来,然后返回一个指向该文件的URL指针。
- (NSURL *)urlForFilename:(NSString *)filename {
NSFileManager * fm = [NSFileManager defaultManager];
NSArray * urls = [fm URLsForDirectory:NSDocumentDirectory
inDomains:NSUserDomainMask];
NSURL * directoryURL = urls[0];
NSURL * fileURL = [directoryURL URLByAppendingPathComponent:filename];
return fileURL;
}
*/ - (NSURL *)urlForFilename:(NSString *)filename
{
// be sure to insert "Documents" into the path
NSURL * baseURL = [[NSFileManager defaultManager]
URLForUbiquityContainerIdentifier:nil];
NSURL * pathURL = [baseURL URLByAppendingPathComponent:@"Documents"];
NSURL * destinationURL = [pathURL URLByAppendingPathComponent:filename];
return destinationURL;
} /* original //也用到了Document目录,用于查找代表现存文档的文件。该方法获取它所找到的文件,并将它们根据创建的时间来排序,以便用户可以以“博客风格”的顺序来查看文档列表(第一个文档是最新的)。文档文件名被存放在documentFilenames属性中,然后重新加载表视图(我们尚未处理)。
- (void)reloadFiles {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask, YES);
NSString *path = paths[0];
NSFileManager *fm = [NSFileManager defaultManager]; NSError *dirError;
NSArray *files = [fm contentsOfDirectoryAtPath:path error:&dirError];
if (!files) {
NSLog(@"Encountered error while trying to list files in directory %@: %@",
path, dirError);
}
NSLog(@"found files: %@", files); files = [files sortedArrayUsingComparator:
^NSComparisonResult(id filename1, id filename2) {
NSDictionary *attr1 = [fm attributesOfItemAtPath:
[path stringByAppendingPathComponent:filename1]
error:nil];
NSDictionary *attr2 = [fm attributesOfItemAtPath:
[path stringByAppendingPathComponent:filename2]
error:nil];
return [attr2[NSFileCreationDate] compare: attr1[NSFileCreationDate]];
}];
self.documentFilenames = files;
[self.tableView reloadData];
}
*/ - (void)reloadFiles {
NSFileManager * fileManager = [NSFileManager defaultManager];
// passing nil is OK here, matches first entitlement
NSURL * cloudURL = [fileManager URLForUbiquityContainerIdentifier:nil];
NSLog(@"got cloudURL %@", cloudURL); // returns nil in simulator self.query = [[NSMetadataQuery alloc] init];
_query.predicate = [NSPredicate predicateWithFormat:@"%K like '*.tinypix'",
NSMetadataItemFSNameKey];
_query.searchScopes = [NSArray arrayWithObject:
NSMetadataQueryUbiquitousDocumentsScope];
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(updateUbiquitousDocuments:)
name:NSMetadataQueryDidFinishGatheringNotification
object:nil];
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(updateUbiquitousDocuments:)
name:NSMetadataQueryDidUpdateNotification
object:nil];
[_query startQuery];
} - (void)updateUbiquitousDocuments:(NSNotification *)notification {
self.documentURLs = [NSMutableArray array];
self.documentFilenames = [NSMutableArray array]; NSLog(@"updateUbiquitousDocuments, results = %@", self.query.results);
NSArray *results = [self.query.results sortedArrayUsingComparator:
^NSComparisonResult(id obj1, id obj2) {
NSMetadataItem *item1 = obj1;
NSMetadataItem *item2 = obj2;
return [[item2 valueForAttribute:NSMetadataItemFSCreationDateKey] compare:
[item1 valueForAttribute:NSMetadataItemFSCreationDateKey]];
}]; for (NSMetadataItem *item in results) {
NSURL *url = [item valueForAttribute:NSMetadataItemURLKey];
[self.documentURLs addObject:url];
[(NSMutableArray *)_documentFilenames addObject:[url lastPathComponent]];
} [self.tableView reloadData];
} - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return ;
} - (NSInteger)tableView:(UITableView *)tableView
numberOfRowsInSection:(NSInteger)section {
return [self.documentFilenames count];
} - (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"FileCell"]; NSString * path = self.documentFilenames[indexPath.row];
cell.textLabel.text = path.lastPathComponent.stringByDeletingPathExtension;
return cell;
} - (IBAction)chooseColor:(id)sender {
NSInteger selectedColorIndex = [(UISegmentedControl *)sender selectedSegmentIndex];
[self setTintColorForIndex:selectedColorIndex]; // NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
// [prefs setInteger:selectedColorIndex forKey:@"selectedColorIndex"];
// [prefs synchronize]; NSUbiquitousKeyValueStore * prefs = [NSUbiquitousKeyValueStore defaultStore];
[prefs setLongLong:selectedColorIndex forKey:@"selectedColorIndex"];
} - (void)setTintColorForIndex:(NSInteger)selectedColorIndex {
UIColor *tint = nil;
switch (selectedColorIndex) {
case :
tint = [UIColor redColor];
break;
case :
tint = [UIColor colorWithRed: green:0.6 blue: alpha:];
break;
case :
tint = [UIColor blueColor];
break;
default:
break;
}
[UIApplication sharedApplication].keyWindow.tintColor = tint;
} - (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated]; // NSUserDefaults * prefs = [NSUserDefaults standardUserDefaults];
// NSInteger selectedColorIndex = [prefs integerForKey:@"selectedColorIndex"]; NSUbiquitousKeyValueStore * prefs = [NSUbiquitousKeyValueStore defaultStore];
NSInteger selectedColorIndex = (int)[prefs longLongForKey:@"selectedColorIndex"]; [self setTintColorForIndex:selectedColorIndex];
[self.colorControl setSelectedSegmentIndex:selectedColorIndex];
} - (void)viewDidLoad
{
[super viewDidLoad]; UIBarButtonItem * addButton = [[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemAdd
target:self
action:@selector(insertNewObject)];
self.navigationItem.rightBarButtonItem = addButton;
[self reloadFiles];
} - (void)insertNewObject {
// get the name
UIAlertView *alert =
[[UIAlertView alloc] initWithTitle:@"Filename"
message:@"Enter a name for your new TinyPix document."
delegate:self
cancelButtonTitle:@"Cancel"
otherButtonTitles:@"Create", nil];
alert.alertViewStyle = UIAlertViewStylePlainTextInput;
[alert show];
} - (void)alertView:(UIAlertView *)alertView
didDismissWithButtonIndex:(NSInteger)buttonIndex {
if (buttonIndex == ) {
NSString *filename = [NSString stringWithFormat:@"%@.tinypix",
[alertView textFieldAtIndex:].text];
NSURL *saveUrl = [self urlForFilename:filename];
self.chosenDocument = [[BIDTinyPixDocument alloc] initWithFileURL:saveUrl];
[self.chosenDocument saveToURL:saveUrl
forSaveOperation:UIDocumentSaveForCreating
completionHandler:^(BOOL success) {
if (success) {
NSLog(@"save OK");
[self reloadFiles];
[self performSegueWithIdentifier:@"masterToDetail"
sender:self];
} else {
NSLog(@"failed to save!");
}
}];
}
} - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if (sender == self) {
// if sender == self, a new document has just been created,
// and chosenDocument is already set. UIViewController * destination = segue.destinationViewController;
if ([destination respondsToSelector:@selector(setDetailItem:)]) {
[destination setValue:self.chosenDocument forKey:@"detailItem"];
}
} else {
// find the chosen document from the tableview
NSIndexPath * indexPath = [self.tableView indexPathForSelectedRow];
NSString * filename = self.documentFilenames[indexPath.row];
NSURL * docUrl = [self urlForFilename:filename];
self.chosenDocument = [[BIDTinyPixDocument alloc] initWithFileURL:docUrl];
[self.chosenDocument openWithCompletionHandler:^(BOOL success) {
if (success) {
NSLog(@"load OK");
UIViewController *destination = segue.destinationViewController;
if ([destination respondsToSelector:@selector(setDetailItem:)]) {
[destination setValue:self.chosenDocument forKey:@"detailItem"];
}
} else {
NSLog(@"failed to load!");
}
}];
}
}
3、创建BIDTinyPixView视图类,用于显示用户可编辑的网格。
#import <UIKit/UIKit.h>
@class BIDTinyPixDocument; @interface BIDTinyPixView : UIView
@property (strong, nonatomic) BIDTinyPixDocument * document;
@end
#import "BIDTinyPixView.h"
#import "BIDTinyPixDocument.h" typedef struct {
NSUInteger row;
NSUInteger column;
} GridIndex; @interface BIDTinyPixView () @property (assign, nonatomic) CGSize blockSize;
@property (assign, nonatomic) CGSize gapSize;
@property (assign, nonatomic) GridIndex selectedBlockIndex; @end @implementation BIDTinyPixView - (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
[self commonInit];
}
return self;
} - (id)initWithCoder:(NSCoder *)aDecoder {
self = [super initWithCoder:aDecoder];
if (self) {
[self commonInit];
}
return self;
} - (void)commonInit{
_blockSize = CGSizeMake(, );
_gapSize = CGSizeMake(, );
_selectedBlockIndex.row = NSNotFound;
_selectedBlockIndex.column = NSNotFound;
} // Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect
{
// Drawing code
if (!_document) return; for (NSUInteger row = ; row < ; row++) {
for (NSUInteger column = ; column < ; column++) {
[self drawBlockAtRow:row column:column];
}
}
} - (void)drawBlockAtRow:(NSUInteger)row column:(NSUInteger)column {
CGFloat startX = (_blockSize.width + _gapSize.width) * ( - column) + ;
CGFloat startY = (_blockSize.height + _gapSize.height) * row + ;
CGRect blockFrame = CGRectMake(startX, startY, _blockSize.width, _blockSize.height);
UIColor *color = [_document stateAtRow:row column:column] ?
[UIColor blackColor] : [UIColor whiteColor];
[color setFill];
[self.tintColor setStroke];
UIBezierPath *path = [UIBezierPath bezierPathWithRect:blockFrame];
[path fill];
[path stroke];
} - (GridIndex)touchedGridIndexFromTouches:(NSSet *)touches {
GridIndex result;
UITouch *touch = [touches anyObject];
CGPoint location = [touch locationInView:self];
result.column = - (location.x * 8.0 / self.bounds.size.width);
result.row = location.y * 8.0 / self.bounds.size.height;
return result;
} - (void)toggleSelectedBlock {
[_document toggleStateAtRow:_selectedBlockIndex.row
column:_selectedBlockIndex.column];
[[_document.undoManager prepareWithInvocationTarget:_document]
toggleStateAtRow:_selectedBlockIndex.row column:_selectedBlockIndex.column];
[self setNeedsDisplay];
} - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
self.selectedBlockIndex = [self touchedGridIndexFromTouches:touches];
[self toggleSelectedBlock];
} - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
GridIndex touched = [self touchedGridIndexFromTouches:touches];
if (touched.row != _selectedBlockIndex.row
|| touched.column != _selectedBlockIndex.column) {
_selectedBlockIndex = touched;
[self toggleSelectedBlock];
}
}
4、添加BIDDetailViewController内容
@interface BIDDetailViewController : UIViewController @property (strong, nonatomic) id detailItem; @end
#import "BIDDetailViewController.h"
#import "BIDTinyPixView.h" @interface BIDDetailViewController ()
@property (weak, nonatomic) IBOutlet BIDTinyPixView *pixView;
- (void)configureView;
@end @implementation BIDDetailViewController #pragma mark - Managing the detail item - (void)setDetailItem:(id)newDetailItem
{
if (_detailItem != newDetailItem) {
_detailItem = newDetailItem; // Update the view.
[self configureView];
}
} - (void)configureView
{
// Update the user interface for the detail item. if (self.detailItem) {
self.pixView.document = self.detailItem;
[self.pixView setNeedsDisplay];
}
} - (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[self configureView];
}
//当用户按下返回按钮回到主列表时,文档实例将在没有进行任何保存操作的情况下被销毁,所以添加如下方法。
//一旦用户离开详情页面,就关闭文档,关闭文档会导致该文档被自动保存,保存工作发生在后台线程中。
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
UIDocument * doc = self.detailItem;
[doc closeWithCompletionHandler:nil];
}
5、添加iCloud支持
创建授权文件
6、如何查询
@property (strong, nonatomic) NSMetadataQuery * query;
@property (strong, nonatomic) NSMutableArray * documentURLs; - (void)reloadFiles {
NSFileManager * fileManager = [NSFileManager defaultManager];
// passing nil is OK here, matches first entitlement
NSURL * cloudURL = [fileManager URLForUbiquityContainerIdentifier:nil];
NSLog(@"got cloudURL %@", cloudURL); // returns nil in simulator self.query = [[NSMetadataQuery alloc] init];
_query.predicate = [NSPredicate predicateWithFormat:@"%K like '*.tinypix'",
NSMetadataItemFSNameKey];
_query.searchScopes = [NSArray arrayWithObject:
NSMetadataQueryUbiquitousDocumentsScope];
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(updateUbiquitousDocuments:)
name:NSMetadataQueryDidFinishGatheringNotification
object:nil];
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(updateUbiquitousDocuments:)
name:NSMetadataQueryDidUpdateNotification
object:nil];
[_query startQuery];
} //实现查询完成时的那些通知
//查询的结果包含在一个NSMetadataItem对象的列表,从中我们可以获取文件URL和创建日期等数据项,我们根据创建日期来排列这些项,然后获取所有的URL以供之后使用。
- (void)updateUbiquitousDocuments:(NSNotification *)notification {
self.documentURLs = [NSMutableArray array];
self.documentFilenames = [NSMutableArray array]; NSLog(@"updateUbiquitousDocuments, results = %@", self.query.results);
NSArray *results = [self.query.results sortedArrayUsingComparator:
^NSComparisonResult(id obj1, id obj2) {
NSMetadataItem *item1 = obj1;
NSMetadataItem *item2 = obj2;
return [[item2 valueForAttribute:NSMetadataItemFSCreationDateKey] compare:
[item1 valueForAttribute:NSMetadataItemFSCreationDateKey]];
}]; for (NSMetadataItem *item in results) {
NSURL *url = [item valueForAttribute:NSMetadataItemURLKey];
[self.documentURLs addObject:url];
[(NSMutableArray *)_documentFilenames addObject:[url lastPathComponent]];
} [self.tableView reloadData];
}
7、保存到哪里
- (NSURL *)urlForFilename:(NSString *)filename
{
// be sure to insert "Documents" into the path
NSURL * baseURL = [[NSFileManager defaultManager]
URLForUbiquityContainerIdentifier:nil];
NSURL * pathURL = [baseURL URLByAppendingPathComponent:@"Documents"];
NSURL * destinationURL = [pathURL URLByAppendingPathComponent:filename];
return destinationURL;
}
8、将首选项保存到iCloud
- (IBAction)chooseColor:(id)sender {
NSInteger selectedColorIndex = [(UISegmentedControl *)sender selectedSegmentIndex];
[self setTintColorForIndex:selectedColorIndex]; // NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
// [prefs setInteger:selectedColorIndex forKey:@"selectedColorIndex"];
// [prefs synchronize]; NSUbiquitousKeyValueStore * prefs = [NSUbiquitousKeyValueStore defaultStore];
[prefs setLongLong:selectedColorIndex forKey:@"selectedColorIndex"];
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated]; // NSUserDefaults * prefs = [NSUserDefaults standardUserDefaults];
// NSInteger selectedColorIndex = [prefs integerForKey:@"selectedColorIndex"]; NSUbiquitousKeyValueStore * prefs = [NSUbiquitousKeyValueStore defaultStore];
NSInteger selectedColorIndex = (int)[prefs longLongForKey:@"selectedColorIndex"];
[self setTintColorForIndex:selectedColorIndex];
[self.colorControl setSelectedSegmentIndex:selectedColorIndex];
}
iCloud之旅的更多相关文章
- 精通iOS开发(第5版)
<精通iOS开发(第5版)> 基本信息 原书名:Beginning ios 6 development:exploring the ios sdk 作者: (美)David Mark ...
- Linq之旅:Linq入门详解(Linq to Objects)
示例代码下载:Linq之旅:Linq入门详解(Linq to Objects) 本博文详细介绍 .NET 3.5 中引入的重要功能:Language Integrated Query(LINQ,语言集 ...
- WCF学习之旅—第三个示例之四(三十)
上接WCF学习之旅—第三个示例之一(二十七) WCF学习之旅—第三个示例之二(二十八) WCF学习之旅—第三个示例之三(二十九) ...
- 【C#代码实战】群蚁算法理论与实践全攻略——旅行商等路径优化问题的新方法
若干年前读研的时候,学院有一个教授,专门做群蚁算法的,很厉害,偶尔了解了一点点.感觉也是生物智能的一个体现,和遗传算法.神经网络有异曲同工之妙.只不过当时没有实际需求学习,所以没去研究.最近有一个这样 ...
- Hadoop学习之旅二:HDFS
本文基于Hadoop1.X 概述 分布式文件系统主要用来解决如下几个问题: 读写大文件 加速运算 对于某些体积巨大的文件,比如其大小超过了计算机文件系统所能存放的最大限制或者是其大小甚至超过了计算机整 ...
- .NET跨平台之旅:在生产环境中上线第一个运行于Linux上的ASP.NET Core站点
2016年7月10日,我们在生产环境中上线了第一个运行于Linux上的ASP.NET Core站点,这是一个简单的提供后端服务的ASP.NET Core Web API站点. 项目是在Windows上 ...
- 【Knockout.js 学习体验之旅】(3)模板绑定
本文是[Knockout.js 学习体验之旅]系列文章的第3篇,所有demo均基于目前knockout.js的最新版本(3.4.0).小茄才识有限,文中若有不当之处,还望大家指出. 目录: [Knoc ...
- 【Knockout.js 学习体验之旅】(2)花式捆绑
本文是[Knockout.js 学习体验之旅]系列文章的第2篇,所有demo均基于目前knockout.js的最新版本(3.4.0).小茄才识有限,文中若有不当之处,还望大家指出. 目录: [Knoc ...
- 【Knockout.js 学习体验之旅】(1)ko初体验
前言 什么,你现在还在看knockout.js?这货都已经落后主流一千年了!赶紧去学Angular.React啊,再不赶紧的话,他们也要变out了哦.身旁的90后小伙伴,嘴里还塞着山东的狗不理大蒜包, ...
随机推荐
- 欧拉图 CCF2016第六次 送货
// 欧拉图 CCF2016第六次 送货 // 思路: // CCF数据很水....这道题有问题 // 先判连通,再dfs边. // 应为输出要满足字典序最小,用vector存图,sort一遍,用st ...
- 链表回文串判断&&链式A+B
有段时间没有练习了,链表回文串判断用到了栈.链式A+B将没有的项用0补充.链表有没有头节点,及结点和链表的区别,即pNode和pHead. //#include<iostream> //u ...
- 题目1433:FatMouse (未解决)
题目描述: FatMouse prepared M pounds of cat food, ready to trade with the cats guarding the warehouse co ...
- 【Spark学习】Apache Spark for 第三方Hadoop分发版
Spark版本:1.1.1 本文系从官方文档翻译而来,转载请尊重译者的工作,注明以下链接: http://www.cnblogs.com/zhangningbo/p/4137979.html
- 编译arm64错误记录
响应2月底appstore 64位APP的上线要求,开始编译IOS arm64版本引擎库.编译arm64遇到一些问题,在此记录. 1. 数据类型的错误 __int64 相关,提示error: expe ...
- javaScript 类型判断
直接上例子: 1 判断是否为数组类型 2 判断是否为字符串类型 3 判断是否为数值类型 4 判断是否为日期类型 5 判断是否为函数 6 判断是否为对象 1 判断是否为数组类型 linenum < ...
- SpringDataMongoDB介绍(一)-入门
SpringDataMongoDB介绍(一)-入门 本文介绍如何应用SpringDataMongoDB操作实体和数据库,本文只介绍最基本的例子,复杂的例子在后面的文章中介绍. SpringDataMo ...
- AutoCAD.NET二次开发:创建自定义菜单的两种方法比较
目前我已经掌握的创建CAD菜单方法有两种: COM方式: http://www.cnblogs.com/bomb12138/p/3607929.html CUI方式: http://www.cnblo ...
- 转载 C#结构体(struct)和类(class)的区别
转载原地址: http://dotnet.9sssd.com/csbase/art/8 C#结构体和类的区别问题:在C#编程语言中,类属于引用类型的数据类型,结构体属于值类型的数据类型,这两种数据类型 ...
- C++中使用函数指针 【瓦特芯笔记】
在C++类中使用函数指针. 类型定义: typedef 返回类型(类名::*新类型)(参数表) //类定义 class CA { public: char lcFun(int a) ...