假设,你在GitHub上托管了项目,但是发现你最近的一次提交出了错。你想要撤销这个提交,那么应该怎么做呢?

假设5c24e50是这次错误提交的SHA,58c4e50是离这次提交最近的一次提交,在命令行下输入如下命令即可从5c24e50回退到58c4e50:

git push origin +58c4e50:master

原文链接见这里

Objective-C 提供了两种内存管理的方法,一是 ARC ,即 Automatic Reference Counting,二是 MRR,即 Manual Retain-release。苹果官方推荐的方法是 ARC,因为使用 ARC 时,我们不需要考虑这些复杂的管理过程,编译器会在编译时自动帮我们加上对应的代码。

继续阅读

本篇文章介绍下KVC的基本使用。

下面是Apple官方文档中对Key-value coding(以下简称为KVC)的定义:

Key-value coding is a mechanism for accessing an object’s properties indirectly, using strings to identify properties, rather than through invocation of an accessor method or accessing them directly through instance variables.

在应用中使用 KVC 是一条重要的设计原则,因为它是 KVO、Core Data、Cocoa Binding等技术的基础,同时也可以简化代码。

继续阅读

最近在做一个FFMPEG相关的项目,目的是用FFMPEG将.h264解码成YUV格式的视频。参考了网上的一些资料,如,将代码贴在这里:

void processH264()
{
 int imageWidth = 512;
 int imageHeight = 288;
 FILE *fp;
 int ret,videoStream;
 AVFormatContext *formatContext = NULL;
 AVCodec *codec;
 AVCodecContext *codecContext = NULL;
 AVFrame *decodedFrame;
 AVPacket packet;
 uint8_t *decodedBuffer;
 unsigned int decodedBufferSize;
 int finishedFrame;

 //初始化环境 
 av_register_all();

 fp = fopen(out_yuv_v, "rb+");
 if (fp == NULL){
 perror("open");
 exit(1);
 }

 ret = avformat_open_input(&formatContext, out_h264_v, NULL, NULL);
 if (ret<0)
 handleError("avformat_open_input error");

 ret = avformat_find_stream_info(formatContext, NULL);
 if (ret<0)
 handleError("av_find_stream_info");

 //打印输入文件的详细信息 
 av_dump_format(formatContext, 0, out_h264_v, 0);


 videoStream = 0;
 codecContext = formatContext->streams[videoStream]->codec;

 codec = avcodec_find_decoder(AV_CODEC_ID_H264);
 if (codec == NULL)
 handleError("avcodec_find_decoder error!\n");

 ret = avcodec_open2(codecContext, codec, NULL);
 if (ret<0)
 handleError("avcodec_open2");

 //分配保存视频帧的空间 
 decodedFrame = avcodec_alloc_frame();
 if (!decodedFrame)
 handleError("avcodec_alloc_frame!");

 //分配解码后视频帧的空间 
 decodedBufferSize = avpicture_get_size(DECODED_OUTPUT_FORMAT, imageWidth, imageHeight);
 decodedBuffer = (uint8_t *)malloc(decodedBufferSize);
 if (!decodedBuffer)
 handleError("malloc decodedBuffer error!");

 av_init_packet(&packet);
 while (av_read_frame(formatContext, &packet) >= 0){
 ret = avcodec_decode_video2(codecContext, decodedFrame, &finishedFrame, &packet);
 if (ret<0)
 handleError("avcodec_decode_video2 error!");
 if (finishedFrame){
 avpicture_layout((AVPicture*)decodedFrame, DECODED_OUTPUT_FORMAT, imageWidth, imageHeight, decodedBuffer, decodedBufferSize);
 ret = fwrite(decodedBuffer, sizeof(uint8_t),decodedBufferSize,fp);
 if (ret<0)
 handleError("write yuv stream error!");
 }

 av_free_packet(&packet);
 }

 /*防止视频解码完毕后丢帧的情况*/
 while (1){
 packet.data = NULL;
 packet.size = 0;
 ret = avcodec_decode_video2(codecContext, decodedFrame, &finishedFrame, &packet);
 if (ret <= 0 && (finishedFrame <= 0))
 break;
 if (finishedFrame){
 avpicture_layout((AVPicture*)decodedFrame, DECODED_OUTPUT_FORMAT, imageWidth, imageHeight, decodedBuffer, decodedBufferSize);
 ret = fwrite(decodedBuffer, sizeof(uint8_t), decodedBufferSize, fp);
 if (ret<0)
 handleError("write yuv stream error!");
 }

 av_free_packet(&packet);
 }

 fclose(fp);
 avformat_close_input(&formatContext);
 free(decodedBuffer);
 av_free(decodedFrame);
 avcodec_close(codecContext);
}

但是在运行到最后一行代码时一直会遇到访问冲突的问题。搜索了Stack Overflow和Google都没有找到解决方案,后来在偶然的情况下,我将
下面这行代码放在了最后,没想到竟然不报错了。特此记录下。

avformat_close_input(&formatContext);