‏现在做什么兼职比较好有‏哪些做‏的比较好,比较‏可靠‏专业的五险一金‏代缴‏平台?

/192.168.76.103:65533
at com.hc360.rsf.rpc.protocol.RsfInvokerClientP2p.invoke(RsfInvokerClientP2p.java:128)
at com.hc360.rsf.rpc.proxy.jdk.JdkInvocationHandler.invoke(JdkInvocationHandler.java:87)
at $Proxy58.getOn(Unknown Source)
at com.hc360.rsf.kvdb.helper.KvdbServiceHelper.getOn(KvdbServiceHelper.java:252)
... 63 more
Caused by: com.hc360.rsf.remoting.TimeoutException: 客户端等待响应超时,timeout=3000 ms
at com.hc360.rsf.remoting.RemotingException.(RemotingException.java:24)
at com.hc360.rsf.remoting.TimeoutException.(TimeoutException.java:25)
at com.hc360.rsf.remoting.exchange.support.DefaultFuture.get(DefaultFuture.java:152)
at com.hc360.rsf.remoting.exchange.support.DefaultFuture.get(DefaultFuture.java:113)
at com.hc360.rsf.remoting.transport.mina.MinaChannel.request(MinaChannel.java:196)
at com.hc360.rsf.rpc.protocol.RsfInvokerClientP2p.invoke(RsfInvokerClientP2p.java:109)
... 66 more专业剧院投影 巴可 RLM-W6报价98000元
来源:pconline 原创&
作者:佚名&
责任编辑:laimaorong&
  【 行情】是一款专业剧院型投影,其具有32分贝超低噪声级,比最接近的竞争产品安静10倍,比同类系统节能33%,提供6,000流明的光输出。而且绿色环保,符合人体工学设计,注重成本,是会议室、大厅和礼堂应用的理想首选。现在商家报价98000元,有需要的朋友可以关注下。
投影机最新价格变动表
之前报价(元)
现价(元)
升跌(元)
采集日期:日     更多行情价格变动请点击
&&&&&&&&&&&&  参数方面,采用了一款UHP灯(超能灯),达到6000流明的超高亮度,标准分辨率达到,投影对比度为2000:1,有效范围1.6-6米。这样的配置是会议室、大厅和礼堂应用的理想首选。  编辑点评:在三片DLP技术中率先实现通常单片DLP系统应用中才具备的上佳颜色饱和度和图像质量。价格经济实惠,能耗低。具有 WUXGA () 分辨率,通用功能可显示各种信号源,完全兼容新一代笔记本电脑。  购买时提及PConline太平洋电脑网将会获取更好的服务或优惠  [参考价格]:&&& 98000元   [销售商家]:北京神州视科科技发展有限公司  [销售地址]:北京市海淀区海淀南路19号时代网络大厦9010室  [联系电话]:010-  [报价查询]:  [行情查询]:
电商新品荟
总排行榜我在第100位之后
参考价:暂无
网友评分: 3.5
浏览本产品的网友还关注:德国原装进口STM RLM60-P-0:1M 压力传感器
浏览次数:27
产品报价:
公司名称:
深圳市子晞仪器仪表有限...
所在地区:
产品型号:
更新时间:
厂商性质:
联系人:方超
(联系我时,请说明是在中国仪表网上看到,谢谢!)
德国原装进口STM RLM60-P-0:1M 压力传感器
德国原装进口STM RLM60-P-0:1M
德国原装进口STM RLM60-P-0:1M 压力传感器深圳市子晞仪器仪表有限公司是成立的致力于为中国大陆广大客户提供一站式欧美原产工控机电设备,仪器仪表,备品备件的采购供应商。联系人:方经理电话:QQ:德国原装进口STM RLM60-P-0:1M 压力传感器Phoenix1944314MSTBVA 2,5/ 2-G BUbaumerPDRD E001.S14.C425P+F227335V15-G-50M-PUR-ABGHengstler0525611RI58-O/& 250EK.47KJPhoenixUCT-TMF 10 GN&Phoenix719087UK& 2,5 N GNP+F117713SLC90-1500-TWAGO252-158&Eaton-Moeller218257M22-XDP-G-X2TurckB5131-0 Nr:6904910附件ABB1SBL0AF16ZB-22-00-22BalluffBCC0CPKBCC M415-6-PSPhoenixVC-M-KV-PG21/M32 ST&ABB2CDO4S203MT-C25H01PhoenixCRIMPFOX CENTRUS 6S CUS&P+F6V31-WM-1,5M-PUR-V31-GMPhoenixRC-17P1N8ABLQ8&PhoenixRC-12S2N12R1EN&BeckhoffC&RockwellVPL-B1003F-CK14AS&KukaKSD1-32自动控制器balluffBOS 16K-AU-0LW-02&Eaton-Moeller3-6ADONB403.6KV 40AMP 2" AIR FUSE 3.6ADONB40balluffBOS 18KF-PA-1PE-C-02&SteuteEx ZS 80 1OE/1S WVD - 3m&P+F220353UB300-18GM40A-I-V1Leuze electronic GmbH + Co. KGODS 96B M/C6-600-S12 Nr: &ABB1SFL2AF205-40-22-13SchmersalTK 016-30YEaton-Moeller124065IZM32B4-U25FGutekunst + Co.KGD-252A-01弹簧Phoenix1408954NBC-R4MC/5,0-94B/R4MCSICKM40Z-&GavazziICB12L50N10PO&BernsteinKCN-T12NS/004-KLSM8&&&&&&&&& CPhoenixHC-B 16-TMS-EEE-PR-DI&ABB1SNK0PL8TurckNI25-CP40-LIU Nr:1535544接近开关WarmbierRSB 58C 13+12-3-4-CAN-W1N-DS4-F2&P+FV1-G-5M-PVC传感器线缆Phoenix2301545FLK 16/24/DV-AI/EZ-DR/200Phoenix1460236HC-B 24-TFQ-H-O1M32GBeckhoffC&PhoenixSD-WMS 10 (SY) YE:.&ifmIN5207&ABB2CCS7S803C-K125Eaton-Moeller166710NZM2-1-XKAEaton-Moeller134473XMI32/3__/06/06/__W/E__/D-SOND-RAL*RockwellMPAS-80152E-TOP&Phoenix1607500SL-5EP1N8A9002Phoenix1766903GMSTB 2,5/ 4-STMDSafety light grids, hand protection, type 4, long sensing distance&Phoenix1859369SAMPLE MC 0,5/11-G-2,54P20 THRRockwell800F-AFAU2CU730&HeliosO/52 加热器PhoenixVC-MEMV-T2-R-M25&SteuteEM 14 WR - 5m&TurckIM72-11EX/L Nr:7520703安全栅Euchner025822GSBF06X08-787ABB1SNK0MC512PA 131-&140 (x10) VerticalDOLDBA AC110V 10-100IPM&Rockwell440T-MS3246ALULT&Murr-9651100PUR 5x1.0 gr& 11mbaumerITD 21 A 4 Y36& 1024 H NI KR5&& S 12HonsbergMR-020GM010流量开关BernsteinHLIW-E-EINR.GC KU13&&& E&&&& CWeitmann & Konrad GmbHArt-Nr:200220信号放大器ABB2TLA0JSBT5 24AC/DCTurckPS400R-304-LI2UPN8X-H1141 Nr:6833448压力传感器Hengstler0522647RI58-O/& 120ES.41KCheidenhainST1277-TTLX10,S-nr:511 395-01编码器Phoenix2832991FL RJ45 PROTECT CAPSICKPBS-RB400SG1SSFGMA0Z&Rockwell100-C09EQ300&P+F266622IEC Etikett bedr fuer #181088ELECTROBA AGMAS-2 80A-120A-160A自动控制器baumerDRC 63/812.133/0..16 BARheidenhainOLD ID:,NEW ID&Murr248624PVC-JZ, 3x1,0mm², grau, 20 mWAGO261-108/331-000&SIEMENS6DD模块ifmE11821&ABB1SDA1S5L 400 PR211-LI-In=320A 4p P MPRockwell440T-AKEYE11MC&MDLS4ER/14-045H&ABB1SDA1T4S 250 PR222DS/P-LSI In=100 3p F FSTRACKZ5140-0&SchmersalEDLRGNVProxitronIKL015.38 G 2319P-15感应传感器baumerGXAMW.1203PA2PhoenixCA-12P1NC22S00&TurckBL20-4DI-24VDC-N Nr:6827013模块Phoenix831593LS-EMLP-AL (60X30) BKRockwell440L-P2KD1280YD&JUMO600097Montagesatz Hutschiene AleuzePRK 96M/N-3366-27&PhoenixSH-8EPC58A8LDLS&BeckhoffC&Belden107872RSUF 12-RKU 12-137/20MMurr-7320700PUR-OB 5x0,34 schwarz UL,CSA+schleppk. 7mSchmersalPS116-Z11-STR-H200ATOSAGRL-10液压阀Phoenix1943548ICV 2,5 HC/ 3-G-5,08BeckhoffC&KLASCHKA GMBH. & CO.KGIAD-18mg100b5-1T2A感应接近开关parkerMBS3C644&WAGO231-674&SAVSAV 340.15-20密封件Eaton-Moeller256273EASY821-DC-TCHengstler0301507&SCHMALZ10.01.01.00342&WAGO857-314&Phoenix1703037PT 1,5/ 4-PH-3,5-A BD:43-46ABB2CSR4DS203NC C32 APR30SICKWF5-60B41CA00, Infrarot Gabel-Lichtschranke, Push-Pull Ausgang, Hell-/Dunkel umschaltbar, Ger&testecker M8, 4-pol, Gabelweite 5 mm, Gabeltiefe 60 mm, Teach-in &ber IO-Link oder, BedienfeldABB1SFA0MP1-7090DOLDAN5971 DC48V 1S&BeckhoffC&B&R Industrie-Elektronik GmbHX67DI1371.L12总线模块ABB1SVR0CC-E RTD/VRockwell140U-QTD3-D60&Eaton-Moeller236517PXL-C3/3NEaton-Moeller254975NWS-BF/SRB/KSZ/6X14balluffMESSRAD BDG MR542.12D&PhoenixPC 5/ 3-ST2-7,62 BKNZ195N2293&PhoenixSAC-4P-MR/0,5-542/ FRSH SCO BK&BalluffBES005NBES M12MI-POC40B-S04GPhoenix1843896MC 1,5/ 5-ST-3,5 GY7035 BD:X2Idec213178LD6A-0GQBABB2CDS5S201M-B32NASIEMENS6SY固定电阻器ABB1SFA3CP3-30Y-10SICKLFH-EB1X0G1AF80ST0&Grossenbacher1210211软管Eaton-MoellerSCFB636SAFECLIP 6 WAY FUSEBANK 63A 550V ACBuehlerNT63-K-VA-M3/L=540 0-100&PhoenixMVSTBW 2,5/ 8-ST-5,08GYBD:NZ07&CognexIMRF-2000-BP635&baumerIFRM 06N17G1/LSICKC40E-&ABB1SBV2LS40P33L02Eaton-Moeller216558M22-LED-RSCHNEIDERXMLF250D2125&AEGAMHE 132M TA 4,400V,7,5W,1500U/min,50Hz,Iso F,IP55,IM B5电机heidenhainID:&RexrothMSM030C-0300-NN-M0-CG1电机ABB1SDA1E2.2N 1600 Ekip Dip LI 4p WMPifmIGT250&Murr-0532000PUR-OB 3x0,34 gelb UL, CSA+robot+schleppk. 20mMurr248648PUR-OB& 2x0,5 schwarz schleppk. 5mPhoenix1711960FK-MCP 1,5/ 4-ST-3,5 GY BD:-17PhoenixMSTBVK 2,5/ 4-G-5,08&Rockwell100-CRFSC48&Rockwell&balluffBTL5-Q-Z-S140&balluffBTL5-E17-M1050-S-SA241-K15&balluffBTL5-A11-M0457-R-S32&Phoenix5043941TMC 1 F1 200& 0,1AHonsbergVD-015GR020流量计Murr-7960150PUR 2x2xAWG22 gesch. gn UL,CSA+schleppk. 1,5mGavazziPMT20GM&Idec213375YC9Z-CNA211MGutekunst + Co.KGD-263P弹簧hydacHDA 3745-A-250-174压力变送器Rockwell42KA-T2KNFK-A2&PhoenixPTSA 1,5/ 7-3,5-Z MC GY-BU&ABB1SFA0PSTB570-690-70GEFRANPY-2-C-010位移传感器BalluffBTL2A3ZBTL5-P5-M1676-J-DEXC-TA12Murr-2863500PUR-OB 4x2x0,25 geschirmt& grau& 35mBalluffBTL1ERPBTL7-E500-M0114-Z-S140PhoenixMSTBT 2,5/ 4-ST BD:9-12&WAGO-000&Hengstler0534242RI76TD/ 1000EH.4A40IF-U0Rockwell140G-G-EOPJ&SICKRanger PIO-Encoder-Y-Leitung&ElobauJ6D8AAA00B&ABB1SCA0OL40W2PBPhoenix2914602UM100 SET 7,60CM GNEaton-Moeller259776NZM1-XAHIV48AC/DCPhoenixKC-0121TEJ8A020&Hengstler0551341RI58-T/&& 30EA.42KFSICKC2C-SA&Hengstler0523087RI58-O/ 1000AS.41TF-EMDUK1D/E7-0EAN&SICKPBT-RB025SG2SS0ALA0Z&IFMWELDING THERMOWELL G1/2 V4A&balluffBES M12EN-PSC20B-BV02&heidenhainAELS406C 读数头Euchner035788KCB4C4C4C4C0000DWSommer-automatic GmbH & Co. KGGP260抓手heidenhainMT12W Id.:光学测量仪零件(读数头)Hengstler0527179RI32-O/& 360AR.14KBRockwellLDAT-S031020-DB&BeckhoffC&Murr-6340400PUR-OB 4x0,34 schw UL, CSA + schleppk. 4mDOLDML7863.81 AC50/60HZ 220-230V 5-100S&HORMEC TECHNIC SAID-NR:764161;Meter Teflonschlauch(25M;D=2.17*1.57 )加油软管PantronSTB-LLA-5&BeckhoffCP60&Phoenix1824159MSTBU 2,5/ 5-STD-5,08PhoenixZB 5,LGS:GLEICHE ZAHLEN 81&Infastaub GmbHINFA-TRONICESM-934Y10R Nr:320314控制单元Phoenix1749379MCDN 1,5/ 6-G1-3,81 P14THRBeckhoffC&Contrinex628-000-697LHL-C55PA-TMS-107-501baumerK50 WD& 11PF4 + 15PF4P+F210554V1-G-30M-PURPhoenix2905641VAL-MB-T1/T2 1500DC-PV/2+VGlacier Garlock Bearings0808DUB滚珠轴承PhoenixSACC-EC-FS-5CON-M16/2,0 SCO&Rockwell194L-A40-1754&JUMO422930 (Freischaltung Reglerkan&le 5-8)Rockwell937A-PR20&EAAC301024阀ABB2CDV4S203M-C10UCH10DatalogicS51-PR-2-C01-NKschunk0304280 DPG-plus 240-1-EX&WAGO235-555/331-000&Phoenix707167DFK-MSTB 2,5/ 9-GPhoenix2744429&balluffBCC A519--VX49W8-020&ABB2CCS5S803C-B32BalluffBNS00LLBNS 819-D06-R12-100-10PhoenixMSTBV 2,5/ 5-GF-5,08 EX&Eaton-Moeller293607BPZ-NZM3-800-MVDOLDBA7905.82 AC50/60HZ 24V 0,15-3S&BalluffBTL19Z0BTL5-S102B-M0230-Z-SU200-KA00,2Phoenix2757636UEGH-SE 2,5 OL NZ94.ABB1SFA3M3SS3-31YPhoenixHC-B 24-AMLD-AL-EVOBUEGEL&ETAESX10-103-DC24V-6A模块Murr-1100000Diode Glied, 0&240VDCPhoenix1445059SAC-5P-M12MS/7,5-PUR/M12FSSH BKRockwell&ABB1SDA1T7V 1250 PR332/P LSIG In=1250A 4p F FPhoenix1445279VS-M12MSD-IP20-LI-93P/10,0Phoenix1404799VS-PPC-J-20-0,2DOLDCC AC/DC24V&Murr-2560500PUR-JZ 3x0,75 grau roboter+schleppk. 5mRockwell1734-ACNR&Murr-6330100PUR-OB 3x0,34 schwarz UL, CSA+schleppk. 1mPhoenixIPC 16/ 7-STGF-10,16&CognexIS-000&WAGO722-209/026-000&Rockwell800FM-LF4&TurckFLDP-IM16-0001 Nr:6825326总线模块Contrinex605-002-125S08-3FUW-020-YNNNRockwell800H-W371J&Phoenix1413361SAC-4P- 0,3-PUR/M 8FS 0,1baumerFSE 050A4006Datalogic&Phoenix3009228UKH& 50 EPbaumerOHDK 14N5101/S35AHBM1-WI/5MM-T位移传感器INAGS 81105&Phoenix1504851SAC-5P- 2,0-PUR/M12FRballuffBTL6-V11V-M5&hydacEDS346-2-016-000压力传感器SICKCLV632-0120&Phoenix1602731RC-19P1NX221JSRockwell440T-MDBLE140E0X&WAGO-000&Phoenix5452863BCVP-500W- 8 BKABB1SNA0BJS12-20BeldenGDML 2016 GB C schwarzSICKPFT-FRB016SF2OSCAMSSZ&SCHMERSALEX-AZ 16-12ZVK-3D,Nr. 传感器ELESA+GANTERGN 552-31-M22X1,5-A-2过滤器REVORA0&Idec202732HW1A-P2YSICKDFS60E-TDAC02048&Phoenix1963308MVSTBR 2,5/ 3-ST-5,08BDG-L1 SOparkerRS10R17S4SN9JW油压传动阀Eaton-Moeller16912T3-1-8/EschmalzSAF 80 NBR-60 G1-4-IG真空吸盘Phoenix1556508SACC-M12-NUT-SHSICKSPL-S120PPS2W04&Rockwell440T-MSSLE11JA&Eaton-Moeller155372XANP-MC-FE80ABalluffBAE00ENBAE PS-XA-1W-24-038-601Infastaub GmbHART-Nr:030064 (Filte:AJB 800-980-22-P)电磁阀Phoenix1820929SAMPLE PTSM 0,5/ 2-2,5-H SMDWHSchmersalT3K 236-02ZPhoenixFMCD 1,5/ 9-ST-3,5YELUBBD+SO&SteuteEM 14 TK - 5m&PhoenixDFMC 1,5/12-ST-3,5-LR&PhoenixPC 6/ 4-ST-10,16 GTBU&Phoenix1766615GMSTBV 2,5/ 7-G-7,62PhoenixMSTBA 2,5/ 8-G THT&SICKBEF-HDSTRK1WF&Murr-6541500PUR 4x0.34 sw UL/CSA+robot+schleppk. 15mPhoenix1944767MSTBVA 2,5/19-G-RNleuzeLSE 96K/P-&BalluffBAM002PBMS CS-P-D12-AD18-00Rockwell1492-EWPL16&baumerBMMH 58S1N24C12/13P2NHengstler0531698RI58-D/&& 60EF.47KHbaumerTG 150/311.113 / 0...200&C/L=100PhoenixA-INL-PG16-P-GY&RockwellMPAI-A3450SM34A&Rockwell855E-20BR7&Rockwell800T-FXT9&Belden53259PRKT 4-07/2 MABB1SNA0RC55 101-&110 (x10) HorizontalPhoenix2804380VAL-MS 320/1+1BalluffBAM012KBIS Z-HG-003BalluffBIS00KNBIS C-141-11/LEaton-Moeller277979DILMC40(RDC24)Rockwell440T-MSRUE11TL&SIEMENS6ES-0AB0I/O模块MDCV/CB1-20&Phoenix2965570UM 45-FLK16/2A/S7Phoenix5452215BCP-500- 4 BKRockwell855D-P25SC20B24Y3Y5Y4&DOLDEC AC50/60HZ 220V 16M&ABB1SDA1T2S 160 MA20 Im=120...240 3p F FballuffBOS 63M-NS-LH13-S4&Phoenix1607815VC-A 2-BMRockwell440F-M0930BYNN&DOLDBN5V 3,3KW&PhoenixKCS-K0234/W17&Contrinex605-000-660CSK-Rockwell800F-12WE178&DOLDBH7925.21 AC/DC24V+AC110V 30-300S&Phoenix1702617ISPC 5/ 2-STGCL-7,62BDMC:RD,BKBeckhoffC&ABB2TLA0Mounting kit for Panic ExitpallRC861CZ097HYM&parkerR4V03-535-30-11G0Q-A1阀门Murr-2352300PUR 5x0.34 gr UL/CSA+schleppk. 23mPhoenix1807036PC 16/ 3-STF-10,16 GYProxitronIKL010.33G感应接近开关Murr-2160800PVC-JZ 3x0,75 grau& 8mRockwell194E-G3665M&BeldenGAN22LU-V24-2260300Murr85675IN: 90...264V& 24V OUT: 24V/2x3,8APhoenixK-3E - OE/15,0-B01/M17 F8 - S&BalluffBNS02E6BNS 813-B02-D12-61-A-10-01-FDreiff25 AT10/2.010皮带ELECTRONICONE62.C58-202E(1/4)0电容器PhoenixSAC-8P-10,0-PVC/M12FS SH&EMODB132S/2AX-L32, Motor no: , 9.2 KW电机Phoenix1619316K-5E-M17 M9/2,0-C00/M17 F8Murr-2110100PVC-OB 4x0,25 grau& 1mHengstler0527187RI32-O/ 1000ER.14KAPhoenixSMSTB 2,5/ 4-G BD:60-63&Rockwell889R-M3AEA-10&ifmIG6193&SICKTBT-1PASE2506GZ&ABB1SFA2CP2-10G-01-LLEONARDSWV 100-04 EGA400.5 G20:1*凸轮开关DOLDGB9024 20A AC50/60HZ 400V 15S Nr.0048263自动控制器PulsESX10-TA100-DC24V2A&Phoenix1990944SPT 1,5/11-V-3,5Rockwell800T-Q12R&WAGO771-&Fuchs UmwelttechnikTKF FB06(TKF EU06)&WAGO236-766&Phoenix1404642SACC-M12FSS-3PECON-PG11-MEuchner084642C-M08F04-04X025PV05,0-ES-084642Eaton-Moeller6081120EWS10062RDMurr-6100060PVC 3x0.25 sw UL/CSA 0,6mABUSLIS-SE自动控制器PhoenixQPD T 2PE1,5 2X8-13 BK&schunkSCHUNK-0316 & &上料气缸 & &Gripper PWG 130-B & & & & & & & & & & & & & & & &Idec211136APN146DNWDatalogic208320OH 18-1 K 130 N4-4fluvo schmalenberger GmbH + Co. KGS25-12/2-0.75, material: cast iron潜水泵Phoenix1460368HC-B 10-TMB-100/O1STM32S-EEEheidenhainERN8编码器Phoenix2905723MACX MCR-EX-SL-NAM-YORockwell889D-R5ACDM-25&ABB1SBV0LS40M93L20Rockwell281D-F23B-25D-RRW&PhoenixNS 35/15 CAP&Phoenix2800812PT-IQ-4X1-12DC-PDOLDMK AC0,5-5A AC240V 1S&RechnerKF0102KFS-5-2-150-15/X2-Y75ABB1SFA0CP9-1020Eaton-Moeller171291SL7-L24RechnerKA0743KAS-95-32-1CO-K-M32-POMPhoenixSAC-3P-M12MS/0,6-PUR/M12FS B&WAGO831-1&Crydom&Murr-6410300PUR-OB 4x0,34 geschirmt& schwarz UL, CSA+schleppk. 3mTurckNI20-CP40-Y1X,8.2V Nr:10111接近开关ABB2CDO7S202-K10H01Murr-6350150PUR 5x0.34 sw UL/CSA+schleppk. 1,5mABB1SDA1E4H/P-LSIGIn=4000A3pWMPGavazziEC3016PPASL-1&baumerITD 40 A 4 Y22& 1024 T NI KR1&&& S 25Murr-6160350PVC-JZ 3x0,75 schwarz& 3,5mRockwell1485P-K1TR4&LeuzePRK 46B/66-S12 NR.接近开关DOPAG Dosiertechnik und Pneumatik AGC418-10-00 PART NO:计量阀CognexISM1403-01&ifmE20723&balluffBTL7-V50T-M0760-P-C003&SICKWTB250-2P1151&END-Armaturen GmbH & Co. KGKA24-EE43/TM24DC&balluffBOS 5K-NO-RR10-S49&hydacEDS 345-1-250-000压力传感器ifmPN2694&Murr277199&PhoenixMC 1,5/ 4-STF-3,81 BKCN23BD4-1&ABB1SCA1OSM160GD4N2M230CDatalogic&OMALS518H070球阀ABB1SNA0KEM-1Hengstler0552569RI58-O/ 2500AK.43TB-D0hydacHDA 4444-A-600-000压力变送器WAGO713-1414&MESSTECHNIKWDS-2500-P96-CA3-P WDS--CA3-P编码器Eaton-Moeller171131Z-BB/UL25/1P1MU/57PhoenixSAC-3P-10,0-100/M 8FR&Hengstler0522245RI58-O/& 500EK.42KADatalogic&&PhoenixSAC-12P- 6,4-35T/FR SH SCO&ABB1SDA1TMA 50-500 XT2 3pFinder49.52.8.024.0060Rockwell43GR-TVB32SL&Fronius34.焊机零件(焊接头)BernsteinTK-44&&&&&&&&&&&&&&&&&&&&&&& BSICKAFM60E-THAA002048 ABSOLUTE ENCODERRockwell440T-AKEYS10HB&HoentzschGO 070 WF流量计附件KTRZahnkranz 90/98联轴器Datalogic7-0404&Phoenix2904276VIP-3/PT/D37SUB/M/HW/C300SICKTSP-1PAG30506MZ&TollokTLK131 55X85工件夹具BeckhoffC&Sommer-automatic GmbH & Co. KGGP240-B工件夹具baumerDrehmo.St&tze M6 l =185-220mmIFMFT-00-A-A-M6&GANTERGN 913.2-M6-20-A&Eaton-Moeller204978STN0,2(400/24)BalluffBTL02TWBTL5-A11-M0650-P-S32Phoenix2905747FLT-ISG-PL-33Eaton-Moeller70104K3X185/5SchmersalASHH-PK-1,5MMurr-2311000PUR 4x0.25 gr UL/CSA+schleppk. 10mPhoenixZFKDSA 1,5-W-5,08- 7&ABB1SDA1E4S-A 3600 PR121/P-LSIG In=3600A 4p W MPBeckhoffC&WALTHER-PRAEZISION Carl Kurt Walther GmbH & Co. KGLP-012-0-WR026-01-2-GL液压接头WarmbierFDK:083H4273&Phoenix712291TCP& 8ABurster Praezisionsmesstechnik GmbH & Co KG负荷传感器Eaton-Moeller183636IZMX40H3-P12F-1Phoenix1762512MDSTB 2,5/17-G1-5,08WAGO231-136/001-000/105-604&Phoenix1843761MCV 1,5/18-G-3,5WarmbierA&Rockwell440T-MKEXE22ABBBBBBBBBBBBBBBBB&Atlanta Antriebssysteme E. Seidenspinner GmbH & Co. KG6555038联轴器Phoenix3076033UTI 2,5-L/LBSpiethMSW45.28(M45&1.5)工件夹具PhoenixUS-EML (D39)&Eaton-Moeller150074INX40B3-25WKnickWG21 A7电源PhoenixEV-GBG3PC-1AC32A-5,0M6,0ESBK01&Eaton-Moeller907989T5-3-SOND*/EA/SVBDatalogic93A051283CAB-8501 IP65 CABLE FAM 8K 1,2mRockwellMPAI-B4300RM32B&Vahleassembly:KDS2/40&& &BalluffBNS03TABNS 819-B03-R08-46-11-S80RDOLDIK AC50/60HZ 230V&Phoenix1425895NBC-500,0-94AGavazziSV150230&BalluffBTL153PBTL7-E100-M0660-B-KA02SICKPBS-CB010SF2FSNBMA0Z&GUNTHER1自动控制器JUMO-041PhoenixA-EXSH-M32-68L-N-S&balluffBES 516-200-S2/1.500"-S5&SchmersalSLC 220-E/R-RFB-HPhoenix1460098HC-B 10-TMQ-H-O1STM25SEaton-Moeller259128NZML2-VE100SCHMALZ10.01.06.00458&Murr-2360300PUR-JZ 3x0,75 grau UL, CSA + schleppk. 3mRechnerKA0231KAS-40-A14-N-K, ATEX, 5 m, L = 70 mmheidenhainLC182 20&m Id:编码器BernsteinMAK-3611-A-1&&&&&&&&&&&&&&&& BMurr90405MNFS-10, 10A 32 V rot, kleinMurr-2914000PUR-OB 8x0,25 geschirmt& grau& 40mEaton-Moeller185817DC1-12011FB-A6SCE1Murr63012SKP 32/1 DEaton-Moeller167104FRCMM-25/4/03-A-NAABBGHS5S290-UA230Gefeg-neckarR 644 110 V 50/60Hz Schutzart IP44K2 Zum Anbau Getriebe M189电机FSGG15-PW620-24D/GS150 .027编码器Belden56922/8 MMurr-2500150PUR 3x0.25 gr UL/CSA+robot+schleppk. 1,5mDOLDLG7927.97PC/61 AC/DC24V 30-300S&HonsbergHR1MV-050GM150流量开关ABB2CCS7S803U-K90PhoenixGIC 2,5/ 6-ST-7,62 BD:1N2N3N&ABB2CCA4DS802N-C125/0.3A德国原装进口STM RLM60-P-0:1M 压力传感器
相关技术文章
信息内容:德国原装进口Burster 12DKD-1270 电阻器
信息内容:德国原装进口Burster
电阻测试仪
产品名称价格地区公司名称更新时间
¥120滁州市
¥25滁州市
面议南京市
面议南京市
面议淮安市
所展示的信息由会员自行提供,内容的真实性、准确性和合法性由发布会员负责,中国仪表网对此不承担任何责任。中国仪表网不涉及用户间因交易而产生的法律关系及法律纠纷,纠纷由您自行协商解决。
友情提醒:本网站仅作为用户寻找交易对象,就货物和服务的交易进行协商,以及获取各类与贸易相关的服务信息的平台。为避免产生购买风险,建议您在购买相关产品前务必确认供应商资质及产品质量。过低的价格、夸张的描述、私人银行账户等都有可能是虚假信息,请采购商谨慎对待,谨防欺诈,对于任何付款行为请您慎重抉择!如您遇到欺诈等不诚信行为,请您立即与中国仪表网联系,如查证属实,中国仪表网会对该企业商铺做注销处理,但中国仪表网不对您因此造成的损失承担责任!
联系人:方超
电话:86-6
传真:86-6
主营产品:机电产品、工程仪器仪表及配件、电脑软硬件、五金机电、金属材料及制品、工业化工原料及
该厂商的产品分类
& & 深圳市子晞仪器仪表有限公司是成立的致力于为中国大陆广大客户提供一站式欧美原产工控机电设备,仪器仪表,备品备件的采购供应商。& &子晞总部位于欧洲航空中心法兰克福,100%原装正品,源头采购,杜绝国内代理、办事处、经销商的层层加价,给您一手的优惠报价,而且通过拼单发货,并与优秀国际物流服务商携手合作,保证货期的准确与快速,带给客户最便捷的购物体验。& & 深圳市子晞仪器仪表有限公司,欧美备件服务专家,您的明智之选,目前公司正在快速发展壮大中,欢迎各位新老客户联系合作,互利共赢!
您感兴趣的其他供应
金牌企业:
金牌企业:
金牌企业:
金牌企业:
金牌企业:
金牌企业:
金牌企业:
金牌企业:
金牌企业:
金牌企业:
金牌企业:
金牌企业:
金牌企业:
金牌企业:
金牌企业:
金牌企业:
金牌企业:
金牌企业:
金牌企业:
金牌企业:
金牌企业:
金牌企业:
金牌企业:
金牌企业:
金牌企业:
金牌企业:
金牌企业:
金牌企业:
金牌企业:
金牌企业:
金牌企业:
金牌企业:
金牌企业:
金牌企业:
金牌企业:
金牌企业:
金牌企业:
金牌企业:
金牌企业:
金牌企业:
金牌企业:
金牌企业:
金牌企业:
金牌企业:
金牌企业:
金牌企业:
金牌企业:
金牌企业:
金牌企业:
金牌企业:
金牌企业:
金牌企业:
金牌企业:
金牌企业:
金牌企业:
金牌企业:
金牌企业:
金牌企业:由于最近项目中在用Realm,所以把自己实践过程中的一些心得总结分享一下。
Realm是由Y Combinator孵化的创业团队开源出来的一款可以用于iOS(同样适用于Swift&Objective-C)和Android的跨平台移动数据库。目前最新版是Realm 2.0.2,支持的平台包括Java,Objective-C,Swift,React Native,Xamarin。
Realm官网上说了好多优点,我觉得选用Realm的最吸引人的优点就三点:
跨平台:现在很多应用都是要兼顾iOS和Android两个平台同时开发。如果两个平台都能使用相同的数据库,那就不用考虑内部数据的架构不同,使用Realm提供的API,可以使数据持久化层在两个平台上无差异化的转换。
简单易用:Core Data 和 SQLite 冗余、繁杂的知识和代码足以吓退绝大多数刚入门的开发者,而换用 Realm,则可以极大地减少学习成本,立即学会本地化存储的方法。毫不吹嘘的说,把官方最新文档完整看一遍,就完全可以上手开发了。
可视化:Realm 还提供了一个轻量级的数据库查看工具,在Mac Appstore 可以下载“Realm Browser”这个工具,开发者可以查看数据库当中的内容,执行简单的插入和删除数据的操作。毕竟,很多时候,开发者使用数据库的理由是因为要提供一些所谓的“知识库”。
“Realm Browser”这个工具调试起Realm数据库实在太好用了,强烈推荐。
如果使用模拟器进行调试,可以通过
[RLMRealmConfiguration defaultConfiguration].fileURL
打印出Realm 数据库地址,然后在Finder中??G跳转到对应路径下,用Realm Browser打开对应的.realm文件就可以看到数据啦.
如果是使用真机调试的话“Xcode-&Window-&Devices(??2)”,然后找到对应的设备与项目,点击Download Container,导出xcappdata文件后,显示包内容,进到AppData-&Documents,使用Realm Browser打开.realm文件即可.
自2012年起, Realm 就已经开始被用于正式的商业产品中了。经过4年的使用,逐步趋于稳定。
1.Realm 安装2.Realm 中的相关术语3.Realm 入门——如何使用4.Realm 使用中可能需要注意的一些问题5.Realm “放弃”——优点和缺点6.Realm 到底是什么?7.总结
一. Realm 安装
使用 Realm 构建应用的基本要求:
iOS 7 及其以上版本, macOS 10.9 及其以上版本,此外 Realm 支持 tvOS 和 watchOS 的所有版本。需要使用 Xcode 7.3 或者以后的版本。
注意 这里如果是纯的OC项目,就安装OC的Realm,如果是纯的Swift项目,就安装Swift的Realm。如果是混编项目,就需要安装OC的Realm,然后要把
文件一同编译进去。
RLMSupport.swift这个文件为 Objective-C 版本的 Realm 集合类型中引入了 Sequence 一致性,并且重新暴露了一些不能够从 Swift 中进行原生访问的 Objective-C 方法,例如可变参数 (variadic arguments)。更加详细的说明见。
安装方法就4种:
一. Dynamic Framework
注意:动态框架与 iOS 7 不兼容,要支持 iOS 7 的话请查看“静态框架”。
下载,并解压;前往Xcode 工程的”General”设置项中,从ios/dynamic/、osx/、tvos/
或者watchos/中将’Realm.framework’拖曳到”Embedded Binaries”选项中。确认Copy items if needed被选中后,点击Finish按钮;在单元测试 Target 的”Build Settings”中,在”Framework Search Paths”中添加Realm.framework的上级目录;如果希望使用 Swift 加载 Realm,请拖动Swift/RLMSupport.swift
文件到 Xcode 工程的文件导航栏中并选中Copy items if needed;如果在 iOS、watchOS 或者 tvOS 项目中使用 Realm,请在您应用目标的”Build Phases”中,创建一个新的”Run Script Phase”,并将
bash &${BUILT_PRODUCTS_DIR}/${FRAMEWORKS_FOLDER_PATH}/Realm.framework/strip-frameworks.sh&
这条脚本复制到文本框中。 因为要绕过,这一步在打包通用设备的二进制发布版本时是必须的。
二.CocoaPods
在项目的Podfile中,添加pod 'Realm',在终端运行pod install。
三.Carthage
1.在Carthage 中添加github &realm/realm-cocoa&,运行carthage update。为了修改用以构建项目的 Swift toolchain,通过--toolchain参数来指定合适的 toolchain。--no-use-binaries参数也是必需的,这可以避免 Carthage 将预构建的 Swift 3.0 二进制包下载下来。 例如:
.apple.dt.toolchain.Swift_2_3
2.从 Carthage/Build/目录下对应平台文件夹中,将 Realm.framework
拖曳到您 Xcode 工程”General”设置项的”Linked Frameworks and Libraries”选项卡中;
3.iOS/tvOS/watchOS: 在您应用目标的“Build Phases”设置选项卡中,点击“+”按钮并选择“New Run Script Phase”。在新建的Run Script中,填写:
/usr/local/bin/carthage copy-frameworks
在“Input Files”内添加您想要使用的框架路径,例如:
$(SRCROOT)/Carthage/Build/iOS/Realm.framework
因为要绕过,这一步在打包通用设备的二进制发布版本时是必须的。
四.Static Framework (iOS only)
下载 并解压,将 Realm.framework 从 ios/static/文件夹拖曳到您 Xcode 项目中的文件导航器当中。确保
Copy items if needed 选中然后单击 Finish;在 Xcode 文件导航器中选择您的项目,然后选择您的应用目标,进入到 Build Phases 选项卡中。在
Link Binary with Libraries 中单击 + 号然后添加libc++.dylib;
二. Realm 中的相关术语
为了能更好的理解Realm的使用,先介绍一下涉及到的相关术语。
RLMRealm:Realm是框架的核心所在,是我们构建数据库的访问点,就如同Core Data的管理对象上下文(managed object context)一样。出于简单起见,realm提供了一个默认的defaultRealm( )的便利构造器方法。
RLMObject:这是我们自定义的Realm数据模型。创建数据模型的行为对应的就是数据库的结构。要创建一个数据模型,我们只需要继承RLMObject,然后设计我们想要存储的属性即可。
关系(Relationships):通过简单地在数据模型中声明一个RLMObject类型的属性,我们就可以创建一个“一对多”的对象关系。同样地,我们还可以创建“多对一”和“多对多”的关系。
写操作事务(Write Transactions):数据库中的所有操作,比如创建、编辑,或者删除对象,都必须在事务中完成。“事务”是指位于write闭包内的代码段。
查询(Queries):要在数据库中检索信息,我们需要用到“检索”操作。检索最简单的形式是对Realm( )数据库发送查询消息。如果需要检索更复杂的数据,那么还可以使用断言(predicates)、复合查询以及结果排序等等操作。
RLMResults:这个类是执行任何查询请求后所返回的类,其中包含了一系列的RLMObject对象。RLMResults和NSArray类似,我们可以用下标语法来对其进行访问,并且还可以决定它们之间的关系。不仅如此,它还拥有许多更强大的功能,包括排序、查找等等操作。
三.Realm 入门——如何使用
由于Realm的API极为友好,一看就懂,所以这里就按照平时开发的顺序,把需要用到的都梳理一遍。
1. 创建数据库
- (void)creatDataBaseWithName:(NSString *)databaseName
NSArray *docPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *path = [docPath objectAtIndex:0];
NSString *filePath = [path stringByAppendingPathComponent:databaseName];
NSLog(@&数据库目录 = %@&,filePath);
RLMRealmConfiguration *config = [RLMRealmConfiguration defaultConfiguration];
config.fileURL = [NSURL URLWithString:filePath];
config.objectClasses = @[MyClass.class, MyOtherClass.class];
config.readOnly = NO;
int currentVersion = 1.0;
config.schemaVersion = currentV
config.migrationBlock = ^(RLMMigration *migration , uint64_t oldSchemaVersion) {
if (oldSchemaVersion & currentVersion) {
[RLMRealmConfiguration setDefaultConfiguration:config];
创建数据库主要设置RLMRealmConfiguration,设置数据库名字和存储地方。把路径以及数据库名字拼接好字符串,赋值给fileURL即可。
objectClasses这个属性是用来控制对哪个类能够存储在指定 Realm 数据库中做出限制。例如,如果有两个团队分别负责开发您应用中的不同部分,并且同时在应用内部使用了 Realm 数据库,那么您肯定不希望为它们协调进行数据迁移您可以通过设置RLMRealmConfiguration的 objectClasses属性来对类做出限制。objectClasses一般可以不用设置。
readOnly是控制是否只读属性。
还有一个很特殊的数据库,内存数据库。
通常情况下,Realm 数据库是存储在硬盘中的,但是您能够通过设置inMemoryIdentifier而不是设置RLMRealmConfiguration中的 fileURL属性,以创建一个完全在内存中运行的数据库。
RLMRealmConfiguration *config = [RLMRealmConfiguration defaultConfiguration];config.inMemoryIdentifier = @&MyInMemoryRealm&;RLMRealm *realm = [RLMRealm realmWithConfiguration:config error:nil];
内存数据库在每次程序运行期间都不会保存数据。但是,这不会妨碍到 Realm 的其他功能,包括查询、关系以及线程安全。
如果需要一种灵活的数据读写但又不想储存数据的方式的话,那么可以选择用内存数据库。(关于内存数据库的性能 和 类属性的 性能,还没有测试过,感觉性能不会有太大的差异,所以内存数据库使用场景感觉不多)
使用内存数据库需要注意的是:
内存数据库会在临时文件夹中创建多个文件,用来协调处理诸如跨进程通知之类的事务。 实际上没有任何的数据会被写入到这些文件当中,除非操作系统由于内存过满,
需要清除磁盘上的多余空间。 才会去把内存里面的数据存入到文件中。(感谢 @酷酷的哀殿 指出)
如果某个内存 Realm 数据库实例没有被引用,那么所有的数据就会被释放。所以必须要在应用的生命周期内保持对Realm内存数据库的强引用,以避免数据丢失。
Realm数据模型是基于标准 Objective-C 类来进行定义的,使用属性来完成模型的具体定义。
我们只需要继承 RLMObject或者一个已经存在的模型类,您就可以创建一个新的 Realm 数据模型对象。对应在数据库里面就是一张表。
#import &Realm/Realm.h&
@interface RLMUser : RLMObject
@property NSString
@property NSInteger
@property NSString
@property NSString
@property RLMArray&Car& *
RLM_ARRAY_TYPE(RLMUser)
@interface Car : RLMObject
@property NSString *carN
@property RLMUser *
RLM_ARRAY_TYPE(Car)
注意,RLMObject 官方建议不要加上 Objective-C的property attributes(如nonatomic, atomic, strong, copy, weak 等等)假如设置了,这些attributes会一直生效直到RLMObject被写入realm数据库。
RLM_ARRAY_TYPE宏创建了一个协议,从而允许 RLMArray&Car&语法的使用。如果该宏没有放置在模型接口的底部的话,您或许需要提前声明该模型类。
关于RLMObject的的关系
1.对一(To-One)关系
对于多对一(many-to-one)或者一对一(one-to-one)关系来说,只需要声明一个RLMObject子类类型的属性即可,如上面代码例子,@property RLMUser *
2.对多(To-Many)关系
通过 RLMArray类型的属性您可以定义一个对多关系。如上面代码例子,@property RLMArray&Car& *
3.反向关系(Inverse Relationship)
链接是单向性的。因此,如果对多关系属性 RLMUser.cars链接了一个 Car实例,而这个实例的对一关系属性 Car.owner又链接到了对应的这个 RLMUser实例,那么实际上这些链接仍然是互相独立的。
@interface Car : RLMObject
@property NSString *carN
@property (readonly) RLMLinkingObjects *
@implementation Car
+ (NSDictionary *)linkingObjectsProperties {
@&owners&: [RLMPropertyDescriptor descriptorWithClass:RLMUser.class propertyName:@&cars&],
这里可以类比Core Data里面xcdatamodel文件里面那些“箭头”
@implementation Book
+ (NSString *)primaryKey {
return @&ID&;
+ (NSDictionary *)defaultPropertyValues{
return @{@&carName&:@&测试& };
+ (NSArray&NSString *& *)ignoredProperties {
return @[@&ID&];
+ (NSArray *)requiredProperties {
return @[@&name&];
+ (NSArray *)indexedProperties {
return @[@&ID&];
还可以给RLMObject设置主键primaryKey,默认值defaultPropertyValues,忽略的属性ignoredProperties,必要属性requiredProperties,索引indexedProperties。比较有用的是主键和索引。
3.存储数据
Car *car = [[Car alloc] init];
car.carName = @&Lamborghini&;
Car *myOtherCar = [[Car alloc] initWithValue:@{@&name& : @&Rolls-Royce&}];
Car *myThirdcar = [[Car alloc] initWithValue:@[@&BMW&]];
注意,所有的必需属性都必须在对象添加到 Realm 前被赋值
[realm beginWriteTransaction];
[realm addObject:Car];
[realm commitWriteTransaction];
请注意,如果在进程中存在多个写入操作的话,那么单个写入操作将会阻塞其余的写入操作,并且还会锁定该操作所在的当前线程。
Realm这个特性与其他持久化解决方案类似,我们建议您使用该方案常规的最佳做法:将写入操作转移到一个独立的线程中执行。
官方给出了一个建议:
由于 Realm 采用了 MVCC 设计架构,读取操作并不会因为写入事务正在进行而受到影响。除非您需要立即使用多个线程来同时执行写入操作,不然您应当采用批量化的写入事务,而不是采用多次少量的写入事务。
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
RLMRealm *realm = [RLMRealm defaultRealm];
[realm transactionWithBlock:^{
[realm addObject: Car];
上面的代码就是把写事务放到子线程中去处理。
[realm beginWriteTransaction];
[realm deleteObject:Car];
[realm deleteObjects:CarResult];
[realm deleteAllObjects];
[realm commitWriteTransaction];
当没有主键的情况下,需要先查询,再修改数据。
当有主键的情况下,有以下几个非常好用的API
[realm addOrUpdateObject:Car];
[Car createOrUpdateInRealm:realm withValue:@{@&id&: @1, @&price&: @9000.0f}];
addOrUpdateObject会去先查找有没有传入的Car相同的主键,如果有,就更新该条数据。这里需要注意,addOrUpdateObject这个方法不是增量更新,所有的值都必须有,如果有哪几个值是null,那么就会覆盖原来已经有的值,这样就会出现数据丢失的问题。
createOrUpdateInRealm:withValue:这个方法是增量更新的,后面传一个字典,使用这个方法的前提是有主键。方法会先去主键里面找有没有字典里面传入的主键的记录,如果有,就只更新字典里面的子集。如果没有,就新建一条记录。
在Realm中所有的查询(包括查询和属性访问)在 Realm 中都是延迟加载的,只有当属性被访问时,才能够读取相应的数据。
查询结果并不是数据的拷贝:修改查询结果(在写入事务中)会直接修改硬盘上的数据。同样地,您可以直接通过包含在RLMResults中的RLMObject对象完成遍历关系图的操作。除非查询结果被使用,否则检索的执行将会被推迟。这意味着链接几个不同的临时 {RLMResults} 来进行排序和匹配数据,不会执行额外的工作,例如处理中间状态。
一旦检索执行之后,或者通知模块被添加之后, RLMResults将随时保持更新,接收 Realm 中,在后台线程上执行的检索操作中可能所做的更改。
RLMResults&Car *& *cars = [Car allObjects];
RLMResults&Dog *& *tanDogs = [Dog objectsWhere:@&color = '棕黄色' AND name BEGINSWITH '大'&];
NSPredicate *pred = [NSPredicate predicateWithFormat:@&color = %@ AND name BEGINSWITH %@&,
@&棕黄色&, @&大&];
RLMResults *results = [Dog objectsWithPredicate:pred];
RLMResults&Dog *& *sortedDogs = [[Dog objectsWhere:@&color = '棕黄色' AND name BEGINSWITH '大'&] sortedResultsUsingProperty:@&name& ascending:YES];
Realm还能支持链式查询
Realm 查询引擎一个特性就是它能够通过非常小的事务开销来执行链式查询(chain queries),而不需要像传统数据库那样为每个成功的查询创建一个不同的数据库服务器访问。
RLMResults&Car *& *Cars = [Car objectsWhere:@&color = blue&];
RLMResults&Car *& *CarsWithBNames = [Cars objectsWhere:@&name BEGINSWITH 'B'&];
8.其他相关特性
1.支持KVC和KVO
RLMObject、RLMResult以及 RLMArray
都遵守键值编码(Key-Value Coding)(KVC)机制。当您在运行时才能决定哪个属性需要更新的时候,这个方法是最有用的。
将 KVC 应用在集合当中是大量更新对象的极佳方式,这样就可以不用经常遍历集合,为每个项目创建一个访问器了。
RLMResults&Person *& *persons = [Person allObjects];
[[RLMRealm defaultRealm] transactionWithBlock:^{
[[persons firstObject] setValue:@YES forKeyPath:@&isFirst&];
[persons setValue:@&地球& forKeyPath:@&planet&];
Realm 对象的大多数属性都遵从 KVO 机制。所有 RLMObject子类的持久化(persisted)存储(未被忽略)的属性都是遵循 KVO 机制的,并且 RLMObject以及 RLMArray中 无效的(invalidated)属性也同样遵循(然而 RLMLinkingObjects属性并不能使用 KVO 进行观察)。
2.支持数据库加密
NSMutableData *key = [NSMutableData dataWithLength:64];
SecRandomCopyBytes(kSecRandomDefault, key.length, (uint8_t *)key.mutableBytes);
RLMRealmConfiguration *config = [RLMRealmConfiguration defaultConfiguration];
config.encryptionKey =
NSError *error = nil;
RLMRealm *realm = [RLMRealm realmWithConfiguration:config error:&error];
if (!realm) {
NSLog(@&Error opening realm: %@&, error);
Realm 支持在创建 Realm 数据库时采用64位的密钥对数据库文件进行 AES-256+SHA2 加密。这样硬盘上的数据都能都采用AES-256来进行加密和解密,并用 SHA-2 HMAC 来进行验证。每次您要获取一个 Realm 实例时,您都需要提供一次相同的密钥。
不过,加密过的 Realm 只会带来很少的额外资源占用(通常最多只会比平常慢10%)。
token = [realm addNotificationBlock:^(NSString *notification, RLMRealm * realm) {
[myViewController updateUI];
[token stop];
[realm removeNotification:self.token];
Realm 实例将会在每次写入事务提交后,给其他线程上的 Realm 实例发送通知。一般控制器如果想一直持有这个通知,就需要申请一个属性,strong持有这个通知。
- (void)viewDidLoad {
[super viewDidLoad];
__weak typeof(self) weakSelf = self;
self.notificationToken = [[Person objectsWhere:@&age & 5&] addNotificationBlock:^(RLMResults&Person *& *results, RLMCollectionChange *change, NSError *error) {
if (error) {
NSLog(@&Failed to open Realm on background worker: %@&, error);
UITableView *tableView = weakSelf.tableView;
if (!changes) {
[tableView reloadData];
[tableView beginUpdates];
[tableView deleteRowsAtIndexPaths:[changes deletionsInSection:0]
withRowAnimation:UITableViewRowAnimationAutomatic];
[tableView insertRowsAtIndexPaths:[changes insertionsInSection:0]
withRowAnimation:UITableViewRowAnimationAutomatic];
[tableView reloadRowsAtIndexPaths:[changes modificationsInSection:0]
withRowAnimation:UITableViewRowAnimationAutomatic];
[tableView endUpdates];
我们还能进行更加细粒度的通知,用集合通知就可以做到。
集合通知是异步触发的,首先它会在初始结果出现的时候触发,随后当某个写入事务改变了集合中的所有或者某个对象的时候,通知都会再次触发。这些变化可以通过传递到通知闭包当的 RLMCollectionChange参数访问到。这个对象当中包含了受 deletions、insertions和 modifications 状态所影响的索引信息。
集合通知对于 RLMResults、RLMArray、RLMLinkingObjects 以及 RLMResults 这些衍生出来的集合来说,当关系中的对象被添加或者删除的时候,一样也会触发这个状态变化。
4.数据库迁移
这是Realm的优点之一,方便迁移。
对比Core Data的数据迁移,实在是方便太多了。关于iOS Core Data 数据迁移 指南请看这篇。
数据库存储方面的增删改查应该都没有什么大问题,比较蛋疼的应该就是数据迁移了。在版本迭代过程中,很可能会发生表的新增,删除,或者表结构的变化,如果新版本中不做数据迁移,用户升级到新版,很可能就直接crash了。对比Core Data的数据迁移比较复杂,Realm的迁移实在太简单了。
1.新增删除表,Realm不需要做迁移
2.新增删除字段,Realm不需要做迁移。Realm 会自行检测新增和需要移除的属性,然后自动更新硬盘上的数据库架构。
举个官方给的数据迁移的例子:
RLMRealmConfiguration *config = [RLMRealmConfiguration defaultConfiguration];
config.schemaVersion = 2;
config.migrationBlock = ^(RLMMigration *migration, uint64_t oldSchemaVersion)
[migration enumerateObjects:Person.className block:^(RLMObject *oldObject, RLMObject *newObject) {
if (oldSchemaVersion & 1) {
newObject[@&fullName&] = [NSString stringWithFormat:@&%@ %@&, oldObject[@&firstName&], oldObject[@&lastName&]];
if (oldSchemaVersion & 2) {
newObject[@&email&] = @&&;
if (oldSchemaVersion & 3) {
[migration renamePropertyForClass:Person.className oldName:@&yearsSinceBirth& newName:@&age&]; }
[RLMRealmConfiguration setDefaultConfiguration:config];
[RLMRealm defaultRealm];
在block里面分别有3种迁移方式,第一种是合并字段的例子,第二种是增加新字段的例子,第三种是原字段重命名的例子。
四. Realm 使用中可能需要注意的一些问题
在我从0开始接触Realm到熟练上手,基本就遇到了多线程这一个坑。可见Realm的API文档是多么的友好。虽然坑不多,但是还有有些需要注意的地方。
1.跨线程访问数据库,Realm对象一定需要新建一个
*** Terminating app due to uncaught exception 'RLMException', reason: 'Realm accessed from incorrect thread.'**
***** First throw call stack:**
CoreFoundation
0xf34b __exceptionPreprocess + 171**
libobjc.A.dylib
0xa321e objc_exception_throw + 48**
BHFangChuang
0xdd4c2b5 -[RLMRealm beginWriteTransaction] + 77**
BHFangChuang
0xdd4c377 -[RLMRealm transactionWithBlock:error:] + 45**
BHFangChuang
0xdd4c348 -[RLMRealm transactionWithBlock:] + 19**
BHFangChuang
0xd7ae __71-[RealmDataBaseHelper updateUserWithLoginDate:andLogoutDate:according:]_block_invoke + 190**
libdispatch.dylib
0xef980 _dispatch_call_block_and_release + 12**
libdispatch.dylib
0x90cd _dispatch_client_callout + 8**
libdispatch.dylib
0xf8366 _dispatch_queue_override_invoke + 1426**
libdispatch.dylib
0xfa3b7 _dispatch_root_queue_drain + 720**
libdispatch.dylib
0xfa08b _dispatch_worker_thread3 + 123**
libsystem_pthread.dylib
0xc8746 _pthread_wqthread + 1299**
libsystem_pthread.dylib
0xc8221 start_wqthread + 13**
**libc++abi.dylib: terminating with uncaught exception of type NSException**
如果程序崩溃了,出现以上错误,那就是因为你访问Realm数据的时候,使用的Realm对象所在的线程和当前线程不一致。
解决办法就是在当前线程重新获取最新的Realm,即可。
2. 自己封装一个Realm全局实例单例是没啥作用的
这个也是我之前对Realm多线程理解不清,导致的一个误解。
很多开发者应该都会对Core Data和Sqlite3或者FMDB,自己封装一个类似Helper的单例。于是我也在这里封装了一个单例,在新建完Realm数据库的时候strong持有一个Realm的对象。然后之后的访问中只需要读取这个单例持有的Realm对象就可以拿到数据库了。
想法是好的,但是同一个Realm对象是不支持跨线程操作realm数据库的。
Realm 通过确保每个线程始终拥有 Realm 的一个快照,以便让并发运行变得十分轻松。你可以同时有任意数目的线程访问同一个 Realm 文件,并且由于每个线程都有对应的快照,因此线程之间绝不会产生影响。需要注意的一件事情就是不能让多个线程都持有同一个 Realm 对象的 实例 。如果多个线程需要访问同一个对象,那么它们分别会获取自己所需要的实例(否则在一个线程上发生的更改就会造成其他线程得到不完整或者不一致的数据)。
其实RLMRealm *realm = [RLMRealm defaultRealm]; 这句话就是获取了当前realm对象的一个实例,其实实现就是拿到单例。所以我们每次在子线程里面不要再去读取我们自己封装持有的realm实例了,直接调用系统的这个方法即可,能保证访问不出错。
3.transactionWithBlock 已经处于一个写的事务中,事务之间不能嵌套
[realm transactionWithBlock:^{
[self.realm beginWriteTransaction];
[self convertToRLMUserWith:bhUser To:[self convertToRLMUserWith:bhUser To:nil]];
[self.realm commitWriteTransaction];
transactionWithBlock 已经处于一个写的事务中,如果还在block里面再写一个commitWriteTransaction,就会出错,写事务是不能嵌套的。
出错信息如下:
*** Terminating app due to uncaught exception 'RLMException', reason: 'The Realm is already in a write transaction'**
***** First throw call stack:**
CoreFoundation
0xe2d34b __exceptionPreprocess + 171**
libobjc.A.dylib
0xb3121e objc_exception_throw + 48**
BHFangChuang
0x02b5 -[RLMRealm beginWriteTransaction] + 77**
BHFangChuang
0xbc4175a __71-[RealmDataBaseHelper updateUserWithLoginDate:andLogoutDate:according:]_block_invoke_2 + 42**
BHFangChuang
0x0380 -[RLMRealm transactionWithBlock:error:] + 54**
BHFangChuang
0x0348 -[RLMRealm transactionWithBlock:] + 19**
BHFangChuang
0xbc416d7 __71-[RealmDataBaseHelper updateUserWithLoginDate:andLogoutDate:according:]_block_invoke + 231**
libdispatch.dylib
0x9980 _dispatch_call_block_and_release + 12**
libdispatch.dylib
0x30cd _dispatch_client_callout + 8**
libdispatch.dylib
0x2366 _dispatch_queue_override_invoke + 1426**
libdispatch.dylib
0x43b7 _dispatch_root_queue_drain + 720**
libdispatch.dylib
0x408b _dispatch_worker_thread3 + 123**
libsystem_pthread.dylib
0xbed746 _pthread_wqthread + 1299**
libsystem_pthread.dylib
0xbed221 start_wqthread + 13**
**libc++abi.dylib: terminating with uncaught exception of type NSException**
4.建议每个model都需要设置主键,这样可以方便add和update
如果能设置主键,请尽量设置主键,因为这样方便我们更新数据,我们可以很方便的调用addOrUpdateObject: 或者 createOrUpdateInRealm:withValue:方法进行更新。这样就不需要先根据主键,查询出数据,然后再去更新。有了主键以后,这两步操作可以一步完成。
5.查询也不能跨线程查询
RLMResults * results = [self selectUserWithAccid:bhUser.accid];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
RLMRealm *realm = [RLMRealm defaultRealm];
[realm transactionWithBlock:^{
[realm addOrUpdateObject:results[0]];
由于查询是在子线程外查询的,所以跨线程也会出错,出错信息如下:
***** Terminating app due to uncaught exception 'RLMException', reason: 'Realm accessed from incorrect thread'**
***** First throw call stack:**
CoreFoundation
0xa34b __exceptionPreprocess + 171**
libobjc.A.dylib
0xe7e21e objc_exception_throw + 48**
BHFangChuang
0xc34ab _ZL10throwErrorP8NSString + 129**
BHFangChuang
0xc177f -[RLMResults count] + 40**
BHFangChuang
0xdf8f3bf -[RealmDataBaseHelper convertToRLMUserWith:LoginDate:LogoutDate:To:] + 159**
BHFangChuang
0xdf8efc1 __71-[RealmDataBaseHelper updateUserWithLoginDate:andLogoutDate:according:]_block_invoke_2 + 81**
BHFangChuang
0xbd320 -[RLMRealm transactionWithBlock:error:] + 54**
BHFangChuang
0xbd2e8 -[RLMRealm transactionWithBlock:] + 19**
BHFangChuang
0xdf8eecf __71-[RealmDataBaseHelper updateUserWithLoginDate:andLogoutDate:according:]_block_invoke + 351**
libdispatch.dylib
0xb63980 _dispatch_call_block_and_release + 12**
libdispatch.dylib
0xb8d0cd _dispatch_client_callout + 8**
libdispatch.dylib
0xb6c366 _dispatch_queue_override_invoke + 1426**
libdispatch.dylib
0xb6e3b7 _dispatch_root_queue_drain + 720**
libdispatch.dylib
0xb6e08b _dispatch_worker_thread3 + 123**
libsystem_pthread.dylib
0xf3c746 _pthread_wqthread + 1299**
libsystem_pthread.dylib
0xf3c221 start_wqthread + 13**
**libc++abi.dylib: terminating with uncaught exception of type **
五. Realm “放弃”——优点和缺点
关于Realm的优点,在官网上也说了很多了,我感触最深的3个优点也在文章开头提到了。
CoreData VS Realm 的对比,可以看看
说到使用 Realm最后的二道门槛,一是如何从其他数据库迁移到Realm,二是Realm数据库的一些限制。
接下来请还在考虑是否使用Realm的同学仔细看清楚,下面是你需要权衡是否要换到Realm数据库的重要标准。(以下描述基于Realm最新版 2.0.2)
1.从其他数据库迁移到Realm
如果从其他数据库迁移到Realm,请看我之前写过的一篇,简单的提一下蛋疼的问题,由于切换了数据库,需要在未来几个版本都必须维护2套数据库,因为老用户的数据需要慢慢从老数据库迁移到Realm,这个有点蛋疼。迁移数据的那段代码需要“恶心”的存在工程里。但是一旦都迁移完成,之后的路就比较平坦了。
关于Core Data迁移过来没有fetchedResultController的问题,这里提一下。由于使用Realm的话就无法使用Core Data的fetchedResultController,那么如果数据库更新了数据,是不是只能通过reloadData来更新tableview了?目前基本上是的,Realm提供了我们通知机制,目前的Realm支持给realm数据库对象添加通知,这样就可以在数据库写入事务提交后获取到,从而更新UI;详情可以参考当然如果仍希望使用NSFetchedResultsController的话,那么推荐使用RBQFetchedResultsController,这是一个替代品,地址是:目前Realm计划在未来实现类似的效果,具体您可以参见这个PR:。
当然,如果是新的App,还在开发中,可以考虑直接使用Realm,会更爽。
以上是第一道门槛,如果觉得迁移带来的代价还能承受,那么恭喜你,已经踏入Realm一半了。那么还请看第二道“门槛”。
2. Realm数据库当前版本的限制
把用户一部分拦在Realm门口的还在这第二道坎,因为这些限制,这些“缺点”,导致App的业务无法使用Realm得到满足,所以最终放弃了Realm。当然,这些问题,有些是可以灵活通过改变表结构解决的,毕竟人是活的(如果真的想用Realm,想些办法,谁也拦不住)
1.类名称的长度最大只能存储 57 个 UTF8 字符。
2.属性名称的长度最大只能支持 63 个 UTF8 字符。
3.NSData以及 NSString属性不能保存超过 16 MB 大小的数据。如果要存储大量的数据,可通过将其分解为16MB 大小的块,或者直接存储在文件系统中,然后将文件路径存储在 Realm 中。如果您的应用试图存储一个大于 16MB 的单一属性,系统将在运行时抛出异常。
4.对字符串进行排序以及不区分大小写查询只支持“基础拉丁字符集”、“拉丁字符补充集”、“拉丁文扩展字符集 A” 以及”拉丁文扩展字符集 B“(UTF-8 的范围在 0~591 之间)。
5.尽管 Realm 文件可以被多个线程同时访问,但是您不能跨线程处理 Realms、Realm 对象、查询和查询结果。(这个其实也不算是个问题,我们在多线程中新建新的Realm对象就可以解决)
6.Realm对象的 Setters & Getters 不能被重载
因为 Realm 在底层数据库中重写了 setters 和 getters 方法,所以您不可以在您的对象上再对其进行重写。一个简单的替代方法就是:创建一个新的 Realm 忽略属性,该属性的访问起可以被重写, 并且可以调用其他的 getter 和 setter 方法。
7.文件大小 & 版本跟踪
一般来说 Realm 数据库比 SQLite 数据库在硬盘上占用的空间更少。如果您的 Realm 文件大小超出了您的想象,这可能是因为您数据库中的 RLMRealm中包含了旧版本数据。
为了使您的数据有相同的显示方式,Realm 只在循环迭代开始的时候才更新数据版本。这意味着,如果您从 Realm 读取了一些数据并进行了在一个锁定的线程中进行长时间的运行,然后在其他线程进行读写 Realm 数据库的话,那么版本将不会被更新,Realm 将保存中间版本的数据,但是这些数据已经没有用了,这导致了文件大小的增长。这部分空间会在下次写入操作时被重复利用。这些操作可以通过调用writeCopyToPath:error:来实现。
解决办法:
通过调用invalidate,来告诉 Realm 您不再需要那些拷贝到 Realm 的数据了。这可以使我们不必跟踪这些对象的中间版本。在下次出现新版本时,再进行版本更新。
您可能在 Realm 使用Grand Central Dispatch时也发现了这个问题。在 dispatch 结束后自动释放调度队列(dispatch queue)时,调度队列(dispatch queue)没有随着程序释放。这造成了直到
RLMRealm 对象被释放后,Realm 中间版本的数据空间才会被再利用。为了避免这个问题,您应该在 dispatch 队列中,使用一个显式的自动调度队列(dispatch queue)。
8.Realm 没有自动增长属性
Realm 没有线程/进程安全的自动增长属性机制,这在其他数据库中常常用来产生主键。然而,在绝大多数情况下,对于主键来说,我们需要的是一个唯一的、自动生成的值,因此没有必要使用顺序的、连续的、整数的 ID 作为主键。
解决办法:
在这种情况下,一个独一无二的字符串主键通常就能满足需求了。一个常见的模式是将默认的属性值设置为 [[NSUUID UUID] UUIDString]
以产生一个唯一的字符串 ID。
自动增长属性另一种常见的动机是为了维持插入之后的顺序。在某些情况下,这可以通过向某个 RLMArray中添加对象,或者使用 [NSDate date]默认值的createdAt属性。
9.所有的数据模型必须直接继承自RealmObject。这阻碍我们利用数据模型中的任意类型的继承。
这一点也不算问题,我们只要自己在建立一个model就可以解决这个问题。自己建立的model可以自己随意去继承,这个model专门用来接收网络数据,然后把自己的这个model转换成要存储到表里面的model,即RLMObject对象。这样这个问题也可以解决了。
Realm 允许模型能够生成更多的子类,也允许跨模型进行代码复用,但是由于某些 Cocoa 特性使得运行时中丰富的类多态无法使用。以下是可以完成的操作:
父类中的类方法,实例方法和属性可以被它的子类所继承子类中可以在方法以及函数中使用父类作为参数
以下是不能完成的:
多态类之间的转换(例如子类转换成子类,子类转换成父类,父类转换成子类等)同时对多个类进行检索多类容器 (RLMArray以及 RLMResults)
10.Realm不支持集合类型
这一点也是比较蛋疼。
Realm支持以下的属性类型:BOOL、bool、int、NSInteger、long、long long、float、double、NSString、NSDate、NSData以及
NSNumber。CGFloat属性的支持被取消了,因为它不具备平台独立性。
这里就是不支持集合,比如说NSArray,NSMutableArray,NSDictionary,NSMutableDictionary,NSSet,NSMutableSet。如果服务器传来的一个字典,key是一个字符串,对应的value就是一个数组,这时候就想存储这个数组就比较困难了。当然Realm里面是有集合的,就是RLMArray,这里面装的都是RLMObject。
所以我们想解决这个问题,就需要把数据里面的东西都取出来,如果是model,就先自己接收一下,然后转换成RLMObject的model,再存储到RLMArray里面去,这样转换一遍,还是可以的做到的。
这里列出了暂时Realm当前办法存在的“缺点”,如果这10点,在自己的App上都能满足业务需求,那么这一道坎也不是问题了。
以上两道砍请仔细衡量清楚,这里还有一篇文章是关于更换数据库的心得体会的,考虑更换的同学也可以看看。这两道坎如果真的不适合,过不去,那么请放弃Realm吧!
六. Realm 到底是什么?
大家都知道Sqlite3 是一个移动端上面使用的小型数据库,FMDB是基于Sqlite3进行的一个封装。
那Core Data是数据库么?
Core Data本身并不是数据库,它是一个拥有多种功能的框架,其中一个重要的功能就是把应用程序同数据库之间的交互过程自动化了。有了Core Data框架以后,我们无须编写Objective-C代码,又可以是使用关系型数据库。因为Core Data会在底层自动给我们生成应该最佳优化过的SQL语句。
那么Realm是数据库么?
Realm 不是 ORM,也不基于 SQLite 创建,而是为移动开发者定制的全功能数据库。它可以将原生对象直接映射到Realm的数据库引擎(远不仅是一个键值对存储)中。
Realm 是一个
,底层是用 C++ 编写的。MVCC 指的是多版本并发控制。
Realm是满足ACID的。原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)。一个支持事务(Transaction)的数据库,必需要具有这四种特性。Realm都已经满足。
1.Realm 采用MVCC的设计思想
MVCC 解决了一个重要的并发问题:在所有的数据库中都有这样的时候,当有人正在写数据库的时候有人又想读取数据库了(例如,不同的线程可以同时读取或者写入同一个数据库)。这会导致数据的不一致性 - 可能当你读取记录的时候一个写操作才部分结束。
有很多的办法可以解决读、写并发的问题,最常见的就是给数据库加锁。在之前的情况下,我们在写数据的时候就会加上一个锁。在写操作完成之前,所有的读操作都会被阻塞。这就是众所周知的读-写锁。这常常都会很慢。Realm采用的是MVCC数据库的优点就展现出来了,速度非常快。
MVCC 在设计上采用了和 Git 一样的源文件管理算法。你可以把 Realm 的内部想象成一个 Git,它也有分支和原子化的提交操作。这意味着你可能工作在许多分支上(数据库的版本),但是你却没有一个完整的数据拷贝。Realm 和真正的 MVCC 数据库还是有些不同的。一个像 Git 的真正的 MVCC 数据库,你可以有成为版本树上 HEAD 的多个候选者。而 Realm 在某个时刻只有一个写操作,而且总是操作最新的版本 - 它不可以在老的版本上工作。
Realm底层是B+树实现的,在Realm团队开源的里面可以看到源码,里面有用bpTree,这是一个B+树的实现。B+ 树是一种树数据结构,是一个n叉树,每个节点通常有多个孩子,一棵B+树包含根节点、内部节点和叶子节点。根节点可能是一个叶子节点,也可能是一个包含两个或两个以上孩子节点的节点。
B+ 树通常用于数据库和操作系统的中。NTFS, ReiserFS, NSS, XFS, JFS, ReFS 和BFS等文件系统都在使用B+树作为元数据索引。B+ 树的特点是能够保持数据稳定有序,其插入与修改拥有较稳定的对数时间复杂度。B+ 树元素自底向上插入。
Realm会让每一个连接的线程都会有数据在一个特定时刻的快照。这也是为什么能够在上百个线程中做大量的操作并同时访问数据库,却不会发生崩溃的原因。
上图很好的展现了Realm的一次写操作流程。这里分3个阶段,阶段一中,V1指向根节点R。在阶段二中,准备写入操作,这个时候会有一个V2节点,指向新的R',并且新建一个分支出来,A'和C'。相应的右孩子指向原来V1指向的R的右孩子。如果写入操作失败,就丢弃左边这个分支。这样的设计可以保证即使失败,也仅仅只丢失最新数据,而不会破坏整个数据库。如果写入成功,那么把原来的R,A,C节点放入Garbage中,于是就到了第三阶段,写入成功,变成了V2指向根节点。
在这个写入的过程中,第二阶段是最关键的,写入操作并不会改变原有数据,而是新建了一个新的分支。这样就不用加锁,也可以解决数据库的并发问题。
正是B+树的底层数据结构 + MVCC的设计,保证了Realm的高性能。
2.Realm 采用了 zero-copy 架构
因为 Realm 采用了 zero-copy 架构,这样几乎就没有内存开销。这是因为每一个 Realm 对象直接通过一个本地 long 指针和底层数据库对应,这个指针是数据库中数据的钩子。
通常的传统的数据库操作是这样的,数据存储在磁盘的数据库文件中,我们的查询请求会转换为一系列的SQL语句,创建一个数据库连接。数据库服务器收到请求,通过解析器对SQL语句进行词法和语法语义分析,然后通过查询优化器对SQL语句进行优化,优化完成执行对应的查询,读取磁盘的数据库文件(有索引则先读索引),读取命中查询的每一行的数据,然后存到内存里(这里有内存消耗)。之后你需要把数据序列化成可在内存里面存储的格式,这意味着比特对齐,这样 CPU 才能处理它们。最后,数据需要转换成语言层面的类型,然后它会以对象的形式返回,比如Objective-C的对象等。
这里就是Realm另外一个很快的原因,Realm的数据库文件是通过memory-mapped,也就是说数据库文件本身是映射到内存(实际上是虚拟内存)中的,Realm访问文件偏移就好比文件已经在内存中一样(这里的内存是指虚拟内存),它允许文件在没有做反序列化的情况下直接从内存读取,提高了读取效率。Realm 只需要简单地计算偏移来找到文件中的数据,然后从原始访问点返回数据结构的值 。
正是Realm采用了 zero-copy 架构,几乎没有内存开销,Realm核心文件格式基于memory-mapped,节约了大量的序列化和反序列化的开销,导致了Realm获取对象的速度特别高效。
3. Realm 对象在不同的线程间不能共享
Realm 对象不能在线程间传递的原因就是为了保证隔离性和数据一致性。这样做的目的只有一个,为了速度。
由于Realm是基于零拷贝的,所有对象都在内存里,所以会自动更新。如果允许Realm对象在线程间共享,Realm 会无法确保数据的一致性,因为不同的线程会在不确定的什么时间点同时改变对象的数据。
要想保证多线程能共享对象就是加锁,但是加锁又会导致一个长时间的后台写事务会阻塞 UI 的读事务。不加锁就不能保证数据的一致性,但是可以满足速度的要求。Realm在衡量之后,还是为了速度,做出了不允许线程间共享的妥协。
正是因为不允许对象在不同的线程间共享,保证了数据的一致性,不加线程锁,保证了Realm的在速度上遥遥领先。
4. 真正的懒加载
大多数数据库趋向于在水平层级存储数据,这也就是为什么你从 SQLite 读取一个属性的时候,你就必须要加载整行的数据。它在文件中是连续存储的。
不同的是,Realm尽可能让 Realm 在垂直层级连续存储属性,你也可以看作是按列存储。
在查询到一组数据后,只有当你真正访问对象的时候才真正加载进来。
5. Realm 中的文件
先来说说中间的Database File
.realm 文件是memory mapped的,所有的对象都是文件首地址偏移量的一个引用。对象的存储不一定是连续的,但是Array可以保证是连续存储。
.realm执行写操作的时候,有3个指针,一个是*current top pointer ,一个是 other top pointer ,最后一个是 switch bit*。
switch bit* 标示着top pointer是否已经被使用过。如果被使用过了,代表着数据库已经是可读的。
the top pointer优先更新,紧接着是the switch bit更新。因为即使写入失败了,虽然丢失了所有数据,但是这样能保证数据库依旧是可读的。
再来说说 .lock file。
.lock文件中会包含 the shared group 的metadata。这个文件承担着允许多线程访问相同的Realm对象的职责。
最后说说Commit logs history
这个文件会用来更新索引indexes,会用来同步。里面主要维护了3个小文件,2个是数据相关的,1个是操作management的。
经过上面的分析之后,深深的感受到Realm就是为速度而生的!在保证了ACID的要求下,很多设计都是以速度为主。当然,Realm 最核心的理念就是对象驱动,这是 Realm 的核心原则。Realm 本质上是一个嵌入式数据库,但是它也是看待数据的另一种方式。它用另一种角度来重新看待移动应用中的模型和业务逻辑。
Realm还是跨平台的,多个平台都使用相同的数据库,是多么好的一件事情呀。相信使用Realm作为App数据库的开发者会越来越多。
文/一缕殇流化隐半边冰霜(简书作者)
原文链接:/p/50e0efb66bdf
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。
本文已收录于以下专栏:
相关文章推荐
Realm错误总结整理
iOS开发者交流QQ群:
一.错误信息:Attempting to modify object outside of a write transacti...
Realm Javaversion 0.89.0
官方文档Getting StartedInstallation工程的build.gradle中添加buildscript {
reposit...
上一篇讨论到添加球员信息后,球员列表没有及时得到修改。这是由于之前我们简单地使用了一个NSMutableArray来管理球员列表,需要我们额外做一些变更通知。而在Core Data和UITableVi...
SQLite简介:
SQLite 是一个开源的嵌入式关系数据库,它在 2000 年由 D. Richard Hipp 发布,它可以减少应用程序管理数据的开销 , SQLite 可移植性好 、 很...
Rx 有两个最基础的类型,和其他一些扩展这两种类型的类。两个核心的类为: Observable 和 Observer。Subject 是同时继承了 Observable 和 Observer。Rx 是...
由于最近项目中在用Realm,所以把自己实践过程中的一些心得总结分享一下。
Realm是由Y Combinator孵化的创业团队开源出来的一款可以用于iOS(同样适用于Swift&Objec...
转载自CocoaChina,原文地址:/ios/35.html
由于最近项目中在用Realm,所...
—————————-官网—————————1 介绍安卓开发的最新趋势,Realm是一个可以替代SQLite以及ORMlibraries的轻量级数据库。相比SQLite,Realm更快并且具有很多现代数...
上一篇我们讲述了如何配置realm,本篇博客我们将开启realm代码之旅。俗话说,无图无真相嘛,一言不合就上图:
再看看我们上篇博客中说到的用chrome查看realm数据库内容:
好长时间没有写关于Android方面的学习文章了,今天给大家带来的是堪称是一个可以替代SQLite以及ORMlibraries的轻量级数据库—Realm移动端数据库。相比SQLite,Realm更快并...
他的最新文章
讲师:李江龙
讲师:司徒正美
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)

我要回帖

更多关于 现在做什么工作比较好 的文章

 

随机推荐