今天终于有空调试之前碰到但未解决的一个问题。问题是这样的:使用http将一个视频文件(mp4格式)下载到documents目录下,拿到这个路径,ios4.3sdk下,iphone模拟器上播放失败,提示:this movie could not be played.,在真机上(iphone,ipad,系统均为4.3)可以正常播放。由于项目时间比较紧加上真机上测试通过,所以没当这是一回事。事隔几天后,xcode和真机都升级到最新的ios5。这次在模拟器上跑同一个程序,同样是无法播放,这次提示是:the operation could not be completed.在真机(系统为ios5.0)上测试,同样报相同的错误,不过这次是中文的:操作不能完成。百思不得其解。期间尝试过禁用ios5的ARC(Automatic Reference Counting),这样修改的原因是由于有文章介绍说ios5的ARC会自动释放对象,所以导致一些莫名其妙的错误。搞了半天,解决没找到禁用ARC的设置,后来发现只有使用xcode4.2创建的工程才有Automatic Reference Counting这个选项,旧版本创建的工程是找不到这项设置的,默认值是为no的。
此路不通,再换一条路继续尝试。根据错误提示,搜索到一篇文章,大意也是说ios4下正常播放的文件在ios5下无法播放。文章提到解决办法为使用NSURL对象作为路径读取文件而不是NSString对象作为路径参数。(使用函数为[NSData dataWithContentsOfFile:tempFilePath];将tempFilePath从NSString改为NSURL)。看完这篇文章后,想想自己程序也是使用NSURL读取文件,并且在最初的时候也遇到过问题,无法打开视频,当时的解决办法是对路径进行编码,在创建NSURL对象。代码如下:
[[NSURLalloc]initWithString:[moviePath stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding]];
这段代码在ios4的真机上运行完全没有问题,但在模拟器(ios4,ios5)和ios5的真机上却不正常了。
于是锁定目标,重点在NSURL上着手,找到一篇文章,是介绍通过NSURL访问本地文件,里面的代码打开文件是使用这样的代码的:
NSURL* url = [NSURL fileURLWithPath:Path];
在完全没头绪的情况下,只能啥都试试了。将这段代码替换已有的代码,这时候奇迹出现了,之前碰到的所有问题在一瞬间全部解决了。
法克+雪特!!!就这么简单。看看输出的路径是这样的:file://localhost/...,想想这样应该才是正确的路径,跟读取程序资源包里文件显示的路径是一个方式的。这时候只能责怪自己学艺不精,对函数没有真正的了解。被其实不是问题的问题困扰了好久,该好好反思了。不能只为做项目而熟悉代码,而是要从为了解代码而去做项目。
这是一个惨痛的教训啊,用一两个小时加上被蚊子无限次攻击这些血淋淋的代价换来了这个bug的解决。
附两个api函数的区别:
+ (id)URLWithString:(NSString *)URLString
Parameters
URLString
The string with which to initialize the NSURL object. Must be a URL that conforms to RFC 2396. This method parses URLString according to RFCs 1738 and 1808. (To create NSURL objects for file system paths, use fileURLWithPath:isDirectory: instead.)
+ (id)fileURLWithPath:(NSString *)path
Parameters
path
The path that the NSURL object will represent. path should be a valid system path. If path begins with a tilde, it must first be expanded with stringByExpandingTildeInPath. If path is a relative path, it is treated as being relative to the current working directory.
Passing nil for this parameter produces an exception.