AE开发中IFeatureClass中Search方法的笔记
最近有一个bug困扰了很久,找了半天终于发现了,现在做个总结,方便以后查阅。
在开发过程中,有一个问题就是IFeatureClass.Search()方法,这个方法中有两个参数。
public IFeatureCursor Search ( IQueryFilter filter, bool Recycling );
第一个参数是查询条件,不多介绍,第二个参数是是否进行垃圾回收,对于这个参数的设置,有很多的学问。网上的查询教程一般都是设置为false。但是也有人提出设置为true的话会更快一些,在arcengine的开发帮助文档中也有提到。
The recycling parameter controls row object allocation behavior. Recycling cursors rehydrate a single feature object on each fetch and can be used to optimize read-only access, for example, when drawing. It is illegal to maintain a reference on a feature object returned by a recycling cursor across multiple calls to NextFeature on the cursor. Features returned by a recycling cursor should not be modified. Non-recycling cursors return a separate feature object on each fetch. The features returned by a non-recycling cursor may be modified and stored with polymorphic behavior.
可以看出,如果设置为true的话,每次IFeatureCursor.NextFeature()所拿到的IFeature就是同一个值,而false则是每次拿到的是其副本。这点很像值和引用之前的关系。下面给出例子。
/// <summary> /// 按行来比较 /// </summary> /// <returns></returns> public IList<DiffRowWith2Dic> GetDiffFeatrRowFirst() { IList<DiffRowWith2Dic> diffRowList = new List<DiffRowWith2Dic>(); IFeatureCursor baseFeatrCursor = _baseFeatrCls.Search(null, false);
//IFeatureCursor baseFeatrCursor = _baseFeatrCls.Search(null, true);
IFeature baseFeatr = baseFeatrCursor.NextFeature(); while (baseFeatr != null) { QueryConstructor queryConstrutor = new QueryConstructor(); IQueryFilter queryFilter = queryConstrutor.CreateQueryFilter(baseFeatr); IFeatureCursor toCmprFeatrCursor = _toCmprFeatrCls.Search(queryFilter, false); IFeature toComprFeatr = toCmprFeatrCursor.NextFeature(); System.Runtime.InteropServices.Marshal.ReleaseComObject(toCmprFeatrCursor); if (toComprFeatr == null) { baseFeatr = baseFeatrCursor.NextFeature(); continue; } foreach (string cmprFld in _cmprFldsList) { if (!IsAttributeSame(baseFeatr, toComprFeatr, cmprFld)) { DiffRowWith2Dic primeDiffRow = new DiffRowWith2Dic(); primeDiffRow.baseFeatr = baseFeatr; primeDiffRow.baseStr = GetDataSetPath(_baseFeatrCls.FeatureDataset.Workspace.PathName); primeDiffRow.toCmprFeatr = toComprFeatr; primeDiffRow.toCmprStr = GetDataSetPath(_toCmprFeatrCls.FeatureDataset.Workspace.PathName); diffRowList.Add(primeDiffRow); break; } } baseFeatr = baseFeatrCursor.NextFeature(); } System.Runtime.InteropServices.Marshal.ReleaseComObject(baseFeatrCursor); //GC.Collect(); return diffRowList; } /// <summary> /// 存储比较结果 /// </summary> public struct DiffRowWith2Dic { public IFeature baseFeatr; public string baseStr; public IFeature toCmprFeatr; public string toCmprStr; }
在一开始,我的baseFeatrCursor是通过_baseFeatrCls.Search(null, true)来拿到的,然后发现每次我diffRowList中的baseFeatr都是一样的,其结果都是通过baseFeatrCursor.NextFeature()拿到的最新的baseFeatr,这个结果就很像是我拿到的只是baseFeatr的一个指针,而不是其中的对象。而toCmprFeatr不会出现上述问题,因为每次的toCmprFeatrCursor都是toCmprFeatrCls新Search()出来的结果,每次只用一次。
把_baseFeatrCls.Search(null, true)该为_baseFeatrCls.Search(null, false)问题就解决了。