object-c中对NSMutableArray中存储对象的内存引用测试
写了这么久的ios程序了,最开始由于项目时间紧,没能深入了解object-c中内存的引用和释放,所以偶尔程序无缘无故的就蹦了。
今天仔细看了下程序中对象的retainCount值,才发现很多代码存在内存泄露问题。
retainCount就是当前对象被引用的次数,对象完全释放后retainCount=0,你在xcode的监视窗口可以看到对象上的属性值(引用类型)都已释放了。
看下面一个例子就明白了。
我在程序初始化时创建了两个链(NSMutableArray),listOfStations,allStations。初始化时这两个链装的东西都一样,后面会根据条件listOfStations中会显示部分allStations中的对象。
{//进入方法体
station *st = [[[station alloc] myInit:xx] autoRelease]; //为了在后面不会忘记减少st的retainCount值,这里先autoRelease(也可以在使用完st后调用[st release])。此行.代码执行后st.retainCount = 1。
.....
[listOfStations addobject:st]; //st.retainCount = 2;
[allStations addobject:st]; //st.retainCount = 3;
//[st release];
.....}
//此时st.retainCount = 2,退出方法后,st会自动调用release一次
下面就是在view关闭时调用的当前窗口的[self.view release],时调用当前窗口类的dealloc方法,释放内存。
从上图可以看出,st在整个使用过程中的引用次数变化。
其实在调用NSMutableArray等链表结构中的removeAllobject方法或release时,首先会掉用链中对象的release方法减少对象的retainCount,如果retainCount=0时,对象内存将被释放。
.NET:在ASPX、ASHX和MVC中使用IOC容器(菜鸟必看)
前言
程序开发的一个良好原则就是:“将使用和创建分开”。5年前有多少人采用这种风格呢?几乎没有。在IOC流行甚至泛滥的今天,还有一些团队没有使用IOC容器,有些是由于历史原因,有些是由于团队的文化。没有采用IOC的团队,找个机会拥抱一下吧。
我一直在用IOC容器,在此介绍一下如何将IOC集成到WebForm和WebMvc的应用系统中。
自动注入到ASPX和ASHX
框架支持
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 7 namespace Happy.Web 8 { 9 public interface IWantAutoDependInjection 10 { 11 } 12 }
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 7 namespace Happy.Web 8 { 9 [AttributeUsage(AttributeTargets.Property, AllowMultiple = false)] 10 public sealed class DependToAttribute : Attribute 11 { 12 public Type DependToType { get; set; } 13 14 public string Key { get; set; } 15 } 16 }
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 7 using System.Web; 8 9 using Microsoft.Practices.ServiceLocation; 10 11 using Happy.ExtensionMethods.Reflection; 12 13 namespace Happy.Web 14 { 15 public class DependInjectionModule : IHttpModule 16 { 17 public void Init(HttpApplication context) 18 { 19 context.PreRequestHandlerExecute += OnPreRequestHandlerExecute; 20 } 21 22 private void OnPreRequestHandlerExecute(object sender, EventArgs e) 23 { 24 if (!(HttpContext.Current.CurrentHandler is IWantAutoDependInjection)) 25 { 26 return; 27 } 28 29 var properties = HttpContext.Current.CurrentHandler.GetType().GetProperties(); 30 31 foreach (var property in properties) 32 { 33 var dependToAttribute = property.GetAttribute<DependToAttribute>(false); 34 35 if (dependToAttribute == null) 36 { 37 continue; 38 } 39 40 var dependType = dependToAttribute.DependToType ?? property.PropertyType; 41 42 var value = ServiceLocator.Current.GetInstance(dependType, dependToAttribute.Key ?? string.Empty); 43 44 property.SetValue(HttpContext.Current.Handler, value); 45 } 46 } 47 48 public void Dispose() 49 { 50 } 51 } 52 }
代码示例
1 <configuration> 2 <system.web> 3 <compilation debug="true" targetFramework="4.5" /> 4 <httpRuntime targetFramework="4.5" /> 5 </system.web> 6 7 <system.webServer> 8 <modules> 9 <add name="DependInjectionModule" type="Happy.Web.DependInjectionModule"/> 10 </modules> 11 </system.webServer> 12 13 </configuration>
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Web; 5 using System.Web.UI; 6 using System.Web.UI.WebControls; 7 8 using Happy.Web; 9 10 namespace WebStudy 11 { 12 public partial class Test : System.Web.UI.Page, IWantAutoDependInjection 13 { 14 [DependTo] 15 public ApplicationService ApplicationService { get; set; } 16 17 protected void Page_Load(object sender, EventArgs e) 18 { 19 this.Response.Write(this.ApplicationService.GetMessage()); 20 } 21 } 22 23 public sealed class ApplicationService 24 { 25 public string GetMessage() 26 { 27 return "段光伟"; 28 } 29 } 30 }
运行结果
自动注入到MVC
框架支持(最新版本)
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 7 using System.Web.Routing; 8 using System.Web.Mvc; 9 10 using Microsoft.Practices.ServiceLocation; 11 12 using Happy.DesignByContract; 13 14 namespace Happy.Web.Mvc 15 { 16 public sealed class ServiceLocationDependencyResolver : IDependencyResolver 17 { 18 private readonly IServiceLocator _serviceLocator; 19 20 public ServiceLocationDependencyResolver(IServiceLocator serviceLocator) 21 { 22 Check.RequireNotNull(serviceLocator, "serviceLocator"); 23 24 _serviceLocator = serviceLocator; 25 } 26 27 public object GetService(Type serviceType) 28 { 29 Check.RequireNotNull(serviceType, "serviceType"); 30 31 try 32 { 33 return _serviceLocator.GetInstance(serviceType); 34 } 35 catch 36 { 37 return null; 38 } 39 } 40 41 public IEnumerable<object> GetServices(Type serviceType) 42 { 43 Check.RequireNotNull(serviceType, "serviceType"); 44 45 try 46 { 47 return _serviceLocator.GetAllInstances(serviceType); 48 } 49 catch 50 { 51 return new List<object>(); 52 } 53 } 54 } 55 }
代码示例
此处省略代码示例,有兴趣的朋友请留言交流。
备注
想象一下,开发人员只需要定义和声明,不需要手工组装(new)会有多爽。IOC容器的配置最好根据约定自动配置。