亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

[原創]obj-c編程15[Cocoa實例02]:KVC和KVO的實際運用

2019-11-14 20:18:46
字體:
來源:轉載
供稿:網友

原文鏈接:obj-c編程15[Cocoa實例02]:KVC和KVO的實際運用

 

    我們在第16和第17篇中分別介紹了obj-c的KVC與KVO特性,當時舉的例子比較fun,太抽象,貌似和實際不沾邊哦。那么下面我們就用一個實際中的例子來看看KVC與KVO是如何運用的吧。

    該例中用到了3種新的控件類型:NSTableView、NSSlider以及簡單的NSTextField類型。按說不能再在Random類里添加不沾邊的新增功能了,但是為了簡單,我還是把所有東西都放在Random類里嘍。程序運行時界面如下:

大家可以看到左上角的文本域控件用來顯示當前音量,因為它和Random類里的str_volume(或者是str_vol_way2以及str_vol_way3)屬性做了綁定,所以它會即時更新音量變化的數值;而文本域控件下方的刻度條控件可以讓用戶更改音量大小(從0 到 100),它和Random類的屬性volume綁定起來,所以改變刻度就會帶來volume屬性值的變化,相當于對volume屬性做寫者操作哦。有童鞋可能不明白文本域是如何隨著刻度條值的變化而變化的,畢竟他們綁定的不是一個屬性?。?/span>

    其實我在這里用了KVO的概念,不過這里我用自己監視的是自己的屬性?。涸赗andom的init方法中設置被觀察者為self,而觀察者也是self,觀察的KeyPath為@"volume",于是乎若刻度條將volume改變(因為它和volume綁定,所以它刻度的改變會導致volume的改變,上面已經說了,會調用volume的寫者方法。),則self,也就是Random的對象自己會收到通知。不過這里要注意,不能夠直接在通知回調方法中直接寫:str_volume = [新值] ,因為你這樣沒有調用str_volume的寫者方法,你是直接改實例變量本身了,這樣文本域不會有變化的:因為文本域控件也對str_volume做了KVO,而且該KVO只能監視到str_volume被寫者方法改變的情況,你直接改它實例變量,自然沒有反應嘍。要解決這個問題,可以有3種方法:

1 將str_volume定義在interface,并聲明屬性,然后在implementation里做@synthesize str_volume,這樣我們用[self setStr_volume或self.str_volume的方法(實例變量str_volume的寫者方法)修改,自然會通知外部監控器。

 

2 手動發送通知,告知屬性被改了,這也是str_vol_way2的方法;

 

3 用屬性的KVC方式修改其值,這也是str_vol_way3的方法啊(注意:str_vol_way3沒有外部接口哦!)。

然后在人語發聲之前用speech的setVolume方法應用當前的音量大小就可以啦,不過注意該方法setVolume的參數是浮點數,取值范圍為0.0 - 1.0,所以我在代碼中要除以100??!

    再看窗口右上方的列表視圖控件,也有幾個地方要注意:

1 它是由幾個控件組成的,鼠標要多選幾次才能選中里面的控件,如果控件選的不對,可能就找不到要設置屬性嘍:

 

2 其Connections Inspector中要連接2個地方:dataSource和delegate。前者用來做數據源的代理,后者做其本身動作的代理哦。如果不設置前者則沒有數據源,就沒東西顯示??;同理,若不設置后者就無法響應用戶的動作哦。切記切記。這里再說說代理,代理就是你調用別的類,可是有些事還是你自己最清楚,所以別的類的有些操作還是得返回來問你自己啊。比如列表視圖控件對于[col,row]位置顯示的內容是不知道的,所以你必須以回調方法的方式告訴它;再者,如果它的當前選中行發生變化了,他也不知道如何處理,所以也要問你,等于是一個當前行改變的事件發生了,Random類必須提供事件處理函數哦。

    最后,NSTableView控件還是要按老規矩和Random類連接起來啊,就在其Referencing Outlets里哦;也就是說它和Random一共發生了3種顯式關系(想歪的自覺面壁去偷笑)如下圖所示:

    好了,上面把主要的問題都大致說過了,啥也不說鳥,下面的都在代碼里嘍(在Cocoa實例02的代碼基礎上修改而來):

 1 // 2 //  Random.h 3 //  mac_test 4 // 5 //  Created by kinds on 14-7-4. 6 //  Copyright (c) 2014年 kinds. All rights reserved. 7 // 8  9 #import "comm.h"10 #import <Cocoa/Cocoa.h>11 12 @interface Random : NSObject {13     IBOutlet NSTextField *text_field;14     IBOutlet NSTableView *tab_view;15     NSString *str_volume;16 }17 18 @PRoperty NSString *str_volume;19 20 -(IBAction)seed:(id)sender;21 -(IBAction)generate:(id)sender;22 23 @end

 

  1 //  2 //  Random.m  3 //  mac_test  4 //  5 //  Created by kinds on 14-7-4.  6 //  Copyright (c) 2014年 kinds. All rights reserved.  7 //  8   9 #import "Random.h" 10  11 @implementation Random{ 12     NSSpeechSynthesizer *speech; 13     NSArray *voices; 14     NSNumber *volume; 15     NSString *str_vol_way2; 16     NSString *str_vol_way3; 17 } 18  19 @synthesize str_volume; 20  21 -(id)init{ 22     self = [super init]; 23     if(self){ 24         speech = [[NSSpeechSynthesizer alloc] initWithVoice:nil]; 25         voices = [NSSpeechSynthesizer availableVoices]; 26         msg(@"%@",voices); 27          28         volume = [NSNumber numberWithInt:0]; 29         str_volume = [NSString stringWithFormat:@"音量:%@",volume]; 30         str_vol_way2 = str_vol_way3 = str_volume; 31         [self addObserver:self forKeyPath:@"volume" / 32                   options:NSKeyValueObservingOptionNew context:nil]; 33     } 34     return self; 35 } 36  37 -(void)observeValueForKeyPath:(NSString *)key_path ofObject:(id)obj / 38     change:(NSDictionary *)change context:(void *)context{ 39         NSNumber *new_val = [change objectForKey:NSKeyValueChangeNewKey]; 40         msg(@"volume is change to %@",new_val); 41         //str_volume = @"A"; 42         self.str_volume = [NSString stringWithFormat:@"音量:%i",[new_val intValue]]; 43          44         //syn way 2 45         [self willChangeValueForKey:@"str_vol_way2"]; 46         str_vol_way2 = str_volume; 47         [self didChangeValueForKey:@"str_vol_way2"]; 48         //syn way 3 49         [self setValue:str_volume forKey:@"str_vol_way3"]; 50 } 51  52 -(void)set_voice{ 53     int idx = (int)(random() % [voices count]); 54     [speech setVoice:[voices objectAtIndex:(NSUInteger)idx]]; 55 } 56  57 -(IBAction)generate:(id)sender{ 58     int i = (int)(random() % 100000000000) + 1; 59     msg(@"i = %d",i); 60     [text_field setIntValue:i]; 61     [self set_voice]; 62     //[speech setVolume:[volume floatValue]]; 63     [speech startSpeakingString:[NSString stringWithFormat:@"%i",i]]; 64 } 65  66 -(IBAction)seed:(id)sender{ 67     srandom((unsigned)time(NULL)); 68     NSString *str = @"the seed is reseted!"; 69     [text_field setStringValue:str]; 70     [speech startSpeakingString:str]; 71 } 72  73 -(void)awakeFromNib{ 74     NSDate *now = [NSDate date]; 75     [text_field setObjectValue:now]; 76 } 77  78 -(NSInteger)numberOfRowsInTableView:(NSTableView *)tv{ 79     return (NSInteger)[voices count]; 80 } 81  82 -(id)tableView:(NSTableView *)tv objectValueForTableColumn:(NSTableColumn *)col / 83 row:(NSInteger)row{ 84     NSString *v = [voices objectAtIndex:row]; 85     return v; 86 } 87  88 -(void)tableViewSelectionDidChange:(NSNotification *)notification{ 89     NSInteger row = [tab_view selectedRow]; 90     if(row == -1) return; 91      92     NSString *str_voice = [voices objectAtIndex:row]; 93     [speech setVoice:str_voice]; 94     [speech setVolume:[volume floatValue]/100]; 95     [speech startSpeakingString:@"test one time!!!測試一下哦?。。?/span>"]; 96     msg(@"new voice = %@",str_voice); 97 } 98  99 -(void)dealloc{100     [self removeObserver:self forKeyPath:@"volume"];101 }102 103 104 @end

 


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
欧美激情精品久久久久久久变态| 亚洲人成网站免费播放| 91精品综合久久久久久五月天| 97**国产露脸精品国产| 日韩中文字幕在线播放| 亚洲成av人乱码色午夜| 国产精品久久久av| 中文字幕精品影院| 亚洲人成毛片在线播放| 国产精品久久久久91| 日韩av理论片| 国产精品免费福利| 久久久久久久久久久亚洲| 成人妇女免费播放久久久| y97精品国产97久久久久久| 国产精品久久久精品| 91高清视频免费观看| 久久久之久亚州精品露出| 国产一区二区美女视频| 国产97在线|日韩| 97国产精品人人爽人人做| 久久久久久成人精品| 午夜精品久久久久久久久久久久久| 欧美成人中文字幕| 欧美成aaa人片在线观看蜜臀| 中文字幕免费国产精品| 久久中文字幕在线视频| 亚洲成人教育av| 国产视频久久久久| 亚洲黄色www| 中日韩美女免费视频网站在线观看| 成人免费看吃奶视频网站| 久久综合久中文字幕青草| 91精品国产成人www| 97碰碰碰免费色视频| 久久手机免费视频| 国产精品自拍网| 国产日韩欧美综合| 黑人巨大精品欧美一区二区一视频| 91国产在线精品| 欧美高清视频在线观看| 国产97在线|日韩| 欧美大成色www永久网站婷| 成人网在线免费观看| 国产精品69av| 欧美性猛交xxxx乱大交| 久久久欧美一区二区| 欧美色videos| 色青青草原桃花久久综合| 久久久精品国产| 欧美电影免费观看大全| 97精品一区二区三区| 日韩亚洲第一页| 久久精品国产清自在天天线| 国产精品99一区| 欧美成人中文字幕| 国产精品美女免费视频| 国产精品久久久久久网站| 九九精品视频在线观看| 欧美在线影院在线视频| 少妇av一区二区三区| 97av视频在线| 欧美国产视频日韩| 久久精品视频中文字幕| 在线激情影院一区| 成人性教育视频在线观看| 不卡中文字幕av| 7m第一福利500精品视频| 亚洲国产欧美一区二区三区久久| 欧美一区二区三区……| 欧美国产日韩一区二区| 成人免费视频网址| 在线日韩日本国产亚洲| 欧美性在线视频| 精品在线观看国产| 久久久久女教师免费一区| 精品久久久久久国产| 亚洲美女视频网| 色婷婷av一区二区三区久久| 欧美国产日本在线| 欧美性xxxx极品hd满灌| 中文字幕亚洲欧美一区二区三区| 亚洲欧美日本伦理| 欧美日韩美女视频| 国产精品激情自拍| 久久免费观看视频| 亚洲社区在线观看| 国产日韩精品在线| 国产精品777| 欧美性xxxxx极品娇小| 亚洲精品ady| 两个人的视频www国产精品| 黑人巨大精品欧美一区二区一视频| 国产99视频在线观看| 成人免费网站在线看| 91精品国产自产在线| 久久九九国产精品怡红院| 亚洲精品91美女久久久久久久| 亚洲人成电影在线| 亚洲最大激情中文字幕| 国产精品99久久久久久www| 欧美性资源免费| 亚洲已满18点击进入在线看片| 蜜臀久久99精品久久久无需会员| 欧美大学生性色视频| 国内精品久久久久久| 国产精品入口免费视频一| 66m—66摸成人免费视频| 日韩电影免费观看中文字幕| 精品精品国产国产自在线| 国产xxx69麻豆国语对白| 国产一区香蕉久久| 九色成人免费视频| 97国产一区二区精品久久呦| 欧美日韩免费区域视频在线观看| 正在播放欧美视频| 91亚洲午夜在线| 午夜剧场成人观在线视频免费观看| 北条麻妃久久精品| 国产精品成人免费电影| 91精品一区二区| 亚洲a成v人在线观看| 欧美一级片在线播放| 成人久久久久久久| 欧美激情免费观看| 久久手机精品视频| 国产偷亚洲偷欧美偷精品| 久久艳片www.17c.com| 欧美日韩在线一区| 久久久免费电影| 欧美尤物巨大精品爽| 亚洲aa在线观看| 欧美日韩亚洲视频一区| 日日狠狠久久偷偷四色综合免费| 欧美成人剧情片在线观看| 精品国产乱码久久久久酒店| 91在线观看免费高清完整版在线观看| 一区国产精品视频| 97久久精品在线| 92国产精品久久久久首页| 亚洲福利在线播放| 久久久精品2019中文字幕神马| 亲子乱一区二区三区电影| 亚洲一区二区三区乱码aⅴ蜜桃女| 日韩久久免费视频| 久久这里只有精品99| 国产精品久久久av| 国产日韩精品综合网站| 国产日韩专区在线| 国自产精品手机在线观看视频| 久久久精品在线观看| 欧美美女操人视频| 97婷婷大伊香蕉精品视频| 欧美日韩成人精品| 国产精品老女人精品视频| 日韩欧美aⅴ综合网站发布| 色偷偷av一区二区三区乱| 在线精品视频视频中文字幕| 久久久久久久久久久网站| 91在线视频成人| 日韩国产一区三区| 欧美激情在线有限公司| 免费不卡欧美自拍视频| 午夜精品一区二区三区在线视|