C语言实例,OC常用传值方法

name age sex
Lucy 22 woman
Lily 23 woman
Tom 24 man
Lucy 22 woman
Lily 23 woman
LiLei 25 man

一起talk C栗子吧(第九十六回:C语言实例--使用共享内存进行进程间通信二)


各位看官们,大家好,上一回中咱们说的是使用共享内存进行进程间通信的例子,这一回咱们接着上一回内容继续说使用共享内存进行进程间通信。闲话休提,言归正转。让我们一起talk C栗子吧!

我们在上一回中介绍了共享内存的概念和相关函数的用法,这一回中我们通过具体的例子来说明如何使用共享内存进行进程间的通信。下面是使用共享内存的具体步骤:

1.定义一个结构体类型,用来当作共享内存的类型; 2.使用shmget函数获取共享内存,代码中的键使用了111这个随机数字; 3.使用shmat函数把共享连接到进程的地址空间中; 4.从共享内存中读取数据,或者向共享内存中写入数据; 5.使用shmdt函数把共享内存从进程的地址空间中分离出来; 6.使用shmctl函数删除共享内存,需要使用的命令:IPC_RMID;

看官们,正文中就不写代码了,详细的代码放到了我的资源中,大家可以点击这里下载使用。

下面是程序的运行结果,请大家参考:

./s -r                                  //运行程序并且使用-r参数,表示启动读取数据的进程
there is not any data in share memory   //这时共享内存中还没有数据
./s -w                                  //运行程序并且使用-w参数,表示启动写入数据的进程
write data into share memory.count:3,data:hello share memory //提示写入的数据
./s -r                                //再次运行程序并且使用-r参数,表示启动读取数据的进程                
the data of share memory.count:3,data:hello share memory  //显示从共享内存中读取的数据

在程序中我们使用参数来区分不同的进程,同时使用一个标记位来判断共享内存中是否有数据。另外,使用共享内存进行进程间通信时需要使用同步机制,比如我们在刚开始运行程序时,因为还没有执行写进程,共享内存中没有数据,这时候,读进程不能从共享内存中读取到数据。

各位看官,关于使用共享内存进行进程间通信的例子咱们就说到这里。欲知后面还有什么例子,且听下回分解 。


 

C栗子吧(第九十六回:C语言实例--使用共享内存进行进程间通信二) 各位看官们,大家好,上一回中咱们说的是使用共享内存进行...

  设计的应用程序要求同时支持SQLserver和Oracle,于是,按照SQLserver标准编写的N多sql语句出现了很多在Oracle中不能正确执行的地方,在此将其中的几点差异简单做下记录:    

在面向对象开发中,经常遇到多个类间传值,总结起来即正向传值,反向传值(利用对象,使用TargetAction,使用协议代理,使用系统自带的Block,使用自定义Block),双向传值(A<—>B)(使用NSUserDefaults进行数据传值,使用系统的UIApplication单例进行传值,使用自己的单例类进行传值,使用通知中心NSNotificationCenter进行传值,使用KVC进行传值)。

List<Person> list_persons = new List<Person>(new Person("Lucy",22,"woman"),new Person("Lily",23,"woman"),new Person("Tom",24,"man"),new Person("Lucy",22,"woman"),new Person("Lily",23,"woman"),new Person("LiLei",25,"man"));

(1)在sqlserver中允许使用分号“;”将多条sql语句进行分隔,然后一并进行执行,但是在Oracle中不允许这样的多条语句同时执行,务必拆分为多条单独语句进行执行才行。    

1.正向传值

 

(2)在sqlserver中,是允许将空字符“”插入到数据库表的Not NULL字段的,但是在Oracle中是不允许这样进行插入的,务必使用正确的数据类型进行填充方可。   

属性传值

如同上表中,名字(name)中重复的想要去除,使用linq进行去重的方法,使用Distinct()根本无法达到要求。那么:

 (3)在sqlserver中执行清除数据库表的操作,即便是数据表内容为空,仍旧能够正确地执行,但是在Oracle中,只有当数据表中的数据不为空的时候,才能删除成功,否则会抛出异常,请保证删除有内容的数据表,或者使用try catch将语句进行异常捕获均可。    

在B类中定义属性用于接收A类传来的数据

var list_distinct = list_Persons.GroupBy(c => c.name).Select(c => c.First());

(4)在sqlserver中,sql语句中对数字型字符串进行拼接的时候,可以直接使用“ ”进行,但是在Oracle中,如果使用“ ”的话,则会将两个数字进行求和,并非是将字符串进行拼接,应该使用concat进行拼接。    

2.反向传值

实际的意思是根据某一列进行分组,然后获取每一组的第一条数据,可以解决此次需求

(5)在sqlserver中,求取当前系统时间的函数为getdate(),在Oracle中使用的函数为SYSDATE。    

1)利用对象反向传值

 

(6)在sqlserver中将时间型字符串插入数据库相应字段时候,如2008-5-9 17:45:22,可以正常执行,但是在Oracle中是不能将这样的数据直接插入数据库中的,需要进行一定的转换方可。 (7)在sqlserver中,在insert数据的时候,数据表的标识字段是不用进行插入的,但是在使用Oracle的时候,因没有“标识”的概念,所以,仍旧需要进行插入。

将A类对象定义成B类的属性进行传值

如,通过KGSubViewController修改 KGRootViewController的Label

KGRootViewController

//在KGRootViewController中定义函数接收返回的数据-backValue:(NSString *)string color:(UIColor *)color{ //将参数的值赋给label label.text = string; //将颜色赋给赋给lable的字体颜色 label.textColor = color;}

界面跳转至KGSubViewController,并将KGRootViewController对象传到KGSubViewController中

-touchesBegan:touches withEvent:(UIEvent *)event{ KGSubViewController * svc = [[KGSubViewController alloc]init]; //让B持有A svc.rvc = self; [self presentViewController:svc animated:YES completion:nil];}

KGSubViewController

//创建一个Root对象@property(nonatomic,retain) KGRootViewController * rvc;//在销毁之前,做一些回传数据的事-touchesBegan:touches withEvent:(UIEvent *)event{ [self.rvc backValue:tf.text color:[UIColor redColor]]; [self dismissViewControllerAnimated:YES completion:nil];}

2)使用TargetAction反向传值

通过指定回传方法和回传对象进行传值

仍以上例为例,实现方法为:KGRootViewController

-touchesBegan:touches withEvent:(UIEvent *)event{ KGSubViewController * svc = [[KGSubViewController alloc]init]; //将回传对象进行指定 svc.target = self; //这里的self是指rootviewcontrller //将回传方法,进行指定 svc.selector = @selector(backValue:); [self presentViewController:svc animated:YES completion:nil];}-backValue:(NSString *)string{ //回传数据方法 label.text = string;}

KGSubViewController

//在这里定义两个属性,用来接收目标和方法,用来进行反向传值//接收要回传的对象@property(nonatomic,retain) id target; //接收回传数据的方法@property(nonatomic,assign) SEL selector;//在销毁之前,将数据回传回去-touchesBegan:touches withEvent:(UIEvent *)event{ //利用保存的target 和 action 来进行回传 if ([self.target respondsToSelector:self.selector]) { [self.target performSelector:self.selector withObject:tf.text]; } [self dismissViewControllerAnimated:YES completion:nil];}

3)使用协议代理反向传值

协议代理是回调中常用的方法,顾名思义,把某个对象要做的事情委托给别的对象去做。那么别的对象就是这个对象的代理,代理它来打理要做的事情。使用协议代理不仅可以正向传值,亦可反向传值。在使用中,需要注意哪个类是委托方,哪个类是代理方。总之:谁传值谁是委托方

如,通过KGSubViewController改变KGRootViewController中label值

在KGSubViewController页面里,制定一个协议

@protocol BackValue <NSObject>//回传数据的协议方法-backValue:(NSString *)string;@end@property(nonatomic,retain) id < BackValue > delegate;

在KGSubViewController使代理方实现方法

-touchesBegan:touches withEvent:(UIEvent *)event{ //代理方实现协议中的方法 [self.delegate backValue:tf.text]; [self dismissViewControllerAnimated:YES completion:nil];}

在KGRootViewController中实现协议 <BackValue>

-touchesBegan:touches withEvent:(UIEvent *)event{ KGSubViewController * svc = [[KGSubViewController alloc]init]; //让A同意B所提出的协议条件 svc.delegate = self; [self presentViewController:svc animated:YES completion:nil];}//实现协议 方法-backValue:(NSString *)string{ label.text = string;}

4)使用系统自带的Block进行反向传值

block是代码块的对象,类似函数指针,调用block如同调用代码块中的代码,利用block可以实现回调。

在系统提供方法中,有很多使用block方法,如界面跳转presentViewController时

将KGRootViewController中label.text值传给KGSubViewController textField.text

-touchesBegan:touches withEvent:(UIEvent *)event{ KGSubViewController * svc = [[KGSubViewController alloc]init]; svc.rvc = self; //OC中,block用来去指向一个匿名的语句块,从而可以当成函数还调用该语句块 //这个方法的第三个参数是一个block,意思说,当弹出来的svc显示完成后,执行block里的内容 [self presentViewController:svc animated:YES completion:^{ //正向传值 svc.textField.text = self.label.text; }];}

将KGSubViewController textField.text值传给 KGRootViewController中label.text

-touchesBegan:touches withEvent:(UIEvent *)event{ [self dismissViewControllerAnimated:YES completion:^{ self.rvc.label.text = self.textField.text; }];}

5)使用自定义Block反向传值

KGSubViewController

//定义一个block的属性@property(nonatomic,copy)void (NSString *);-touchesBegan:touches withEvent:(UIEvent *)event{ //执行block self.block; [self dismissViewControllerAnimated:YES completion:nil];}

KGRootViewController

-touchesBegan:touches withEvent:(UIEvent *)event{ KGSubViewController * svc = [[KGSubViewController alloc]init]; //给block赋值,做用是让svc知道block指向的代码块的功能 svc.block = ^(NSString * string){ label.text = string; }; [self presentViewController:svc animated:YES completion:nil];}

3.双向产值1)使用NSUserDefaults进行数据传值

NSUserDefaults纪录本地一些轻量级的数据,是单例类。其通过userDefaults对象来将选中按钮的索引给保存到NSUserDefaults的plist文件中。这个文件实际上是一个plist文件,在沙盒中的/Library/Preferences/NSUserDefaults.plist 这个位置

当KGSubViewController调用viewWillAppear时读取沙盒内容

-viewWillAppear:animated{ [super viewWillAppear:animated]; //获取NSUserDefaults文件,读取里面内容,来决定让哪一个按钮进行选中 NSUserDefaults * ud = [NSUserDefaults standardUserDefaults]; //通过存的时候的key值来进行取值 NSString * value = (NSString *)[ud objectForKey:@"ButtonIndex"]; //计算出按钮的tag值 int buttonIndex = 1000   value.intValue; //利用tag值取到按钮 UIButton * button = (UIButton *)[self.view viewWithTag:buttonIndex]; button.selected = YES;}

KGRootViewController点击button将点击按钮的索引存入沙盒中

-buttonClick:(UIButton *)button{ for (int i = 1;i<6; i  ) { UIButton * btn = (UIButton *)[self.view viewWithTag:1000 i]; if (btn.selected == YES) { btn.selected = NO; } } button.selected = YES; //将每次点击选中的按钮索引给存起来 NSUserDefaults * userDefaults = [NSUserDefaults standardUserDefaults]; NSLog(@"%@",[NSBundle mainBundle]); //通过userDefaults对象来将选中按钮的索引给保存到NSUserDefaults的plist文件中 //这个文件实际上是一个plist文件,在沙盒中的/Library/Preferences/NSUserDefaults.plist 这个位置 [userDefaults setObject:[NSString stringWithFormat:@"%d",button.tag - 1000] forKey:@"ButtonIndex"]; //回写文件 [userDefaults synchronize]; //synchronize:使同步,同时发生}

KGRootViewController

-viewWillAppear:animated{ [super viewWillAppear:animated]; //获取NSUserDefaults文件,读取里面内容,来决定让哪一个按钮进行选中 NSUserDefaults * ud = [NSUserDefaults standardUserDefaults]; //通过存的时候的key值来进行取值 NSString * value = (NSString *)[ud objectForKey:@"ButtonIndex"]; label.text = [NSString stringWithFormat:@"上次按下的是第 %@ 个按钮",value];}

2)使用系统的UIApplication单例进行传值

单例类在程序中只创建一次实例对象,利用这个特点可以进行传值。在iOS开发中,UIApplication就是个单例类,利用他可实现传值。

在UIApplication定义存储内容

//创建一个公共数组,用来存放数据,@property(nonatomic,retain) NSMutableArray * array;

在相应ViewController中使用

//应该去利用系统的UIApplication这个单例来获取系统已经创建好的那个AppDelegate里的对象//这是一个单例 对象,在整个程序中,只有一个唯一的实例存在UIApplication * application = [UIApplication sharedApplication];//通过这个单例对象来找到它持有的AppDelegate对象KGAppDelegate * appDelegate = application.delegate;//通过appDelegate对象拿到他的数组[appDelegate.array addObject:self.title];

3)使用自己的单例类进行传值

除了使用系统自带的单例类外,还可以使用自定义单例类用来传值

自定义单例类KGMyApplication

//为application类,添加一个属性,用来接收MyAppDelegate对象@property(nonatomic,retain) KGMyAppDelegate * delegate;//使用这个方法来实例一个单例对象 (KGMyApplication *)sharedMyApplication; (KGMyApplication *)sharedMyApplication{ static KGMyApplication * obj = nil; if  { //给obj创建单例对象 obj = [[KGMyApplication alloc]init]; //给单例对象的delegate属性赋值 obj.delegate = [[KGMyAppDelegate alloc]init]; } return obj;}

定义KGMyAppDelegate类保存数据

//这个类不是一个单例类,但是,需要在这里保存数据@property(nonatomic,retain)NSMutableArray * array;

在相应ViewController中使用

//首先获取MyApplication的单例对象KGMyApplication * app = [KGMyApplication sharedMyApplication];//通过这个单例对象里的delegate属性来获取MyAppDelegate对象KGMyAppDelegate * appDelegate = app.delegate;//获取MyAppDelegate里的数组NSMutableArray * array = [appDelegate array];static int n = 0;[array addObject:[NSString stringWithFormat:@"VC1-%d",n  ]];

4)使用通知中心NSNotificationCenter进行传值

通知由通知中心发送,通知中心在整个工程中只有一个。通知中心可以发送多条消息,可以在整个工程中的任何位置接收消息,通过通知中心的名称区分消息。

一个简单的应用,从界面2中发送通知,界面1中接收

KGFirstViewController

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(doSomeThing:) name:@"xiaoxi" object:nil];- doSomeThing:(NSNotification *)noti{ NSLog; label.text = [noti.userInfo objectForKey:@"key"];}

KGSecondViewController

NSNotification *noti = [[NSNotification alloc]initWithName:@"xiaoxi" object:self userInfo:[NSDictionary dictionaryWithObjectsAndKeys:[NSString stringWithFormat:@"%@", btn.titleLabel.text],@"key", nil]]; // 发送 [[NSNotificationCenter defaultCenter] postNotification:noti];

类间传值是编程时最常用的方法,也是最基础的语法。在程序中使用不同的方法可以使的程序编的更加灵活。除以上方法外,还有KVC等方法,将在后续详解。

欢迎各位指教

本文由星彩网app下载发布于计算机编程,转载请注明出处:C语言实例,OC常用传值方法

TAG标签: 星彩网app下载
Ctrl+D 将本页面保存为书签,全面了解最新资讯,方便快捷。