现在的位置: 首页 > 综合 > 正文

与主线程相同生命周期的独立线程问题

2013年09月15日 ⁄ 综合 ⁄ 共 2579字 ⁄ 字号 评论关闭

这里只是分享一下,我在写一个处理线程时遇到的问题以及处理方法。

由于各种原因,处理线程需要在主线程启动后,就启动。

而这个线程需要在当前类被释放后,而在外部要停止一个线程也不是那么容易,最好让其自动停止,所以当这个线程启动后,就直接一个while循环中,通过一个条件变量来控制这个这个线程的正常寿终与否。当主线程要这个线程停止时, 就更改这个while中的变量即可。如果主线程只是想要这个子线程暂时停止处理时,可以通过变量decodeIsHandling来进行控制.

// 这里还要说的是这个NSAutoreleasePool, 首先,遵循苹果的原则, 线程起初加入建立一个autoreleasePool, 线程最后一句加入autoreleasePool release。

由于线程主要在while中的else中执行代码,所以需要在这个else中添另一个autoreleasePool以便及时释放临时内存,之前我没有在这个else之中加入autoreleasePool,所以导致这里面的自动释放的内存一直得不到释放,而导致运行30分钟左右,出现系统紧急错误而崩溃,原因就是只有当这个while停止时, 这批自动释放的对象才能得到释放,而要这个while停止时,一般就是程序即出时需要做的操作。

另外一点是, 在子线程中要更改主线程的界面操作, 一定需要调用performSelectorOnMainThread才能做到。没其它办法。

我尝试在子线程中抛出Notification对象,给主线程,主线程再根据notification中的数据来显示,结果发现主线程确实收到这个notificaiton,并取得notification的对象数据,但就是显示不出来,或者说是只显示最后一次调用notification时的界面绘制。

所以切记。

上代码,各位看官可自行分析。

- (void)frameDecodeThread {

   NSAutoreleasePool *decodeThreadPool = [[NSAutoreleasePoolalloc]init]; 

    

   while (decodeThreadShouldRun) {

       
if
(decodeIsHandling ==
NO
) {

           
//
空转等待开始处理

           usleep(DEFAULTEMPTYRUNLOOP *1000);

           NSLog(@"Empty run in while roop");

           
continue
;

        }else {

           NSAutoreleasePool *whilePool = [[NSAutoreleasePoolalloc]init];

// 处理一个,先判断条件是否满足,如果

NSDictionary mediaDic = /..判断处理前提../

            //表示里面没有数据,等待缓冲

           
if
(mediaDic == nil) {     
//
睡默认时间

                curTime = [NSDatetimeIntervalSinceReferenceDate];

               // curTime-lastTime相减得到的值是以秒为单位,而这里进行计算均是按毫秒计算的,usleep是以微秒计算

               
if
((DEFAULTFRAMEINTERVAL <= (curTime-lastTime)*1000)) {

                   
//
表示已经超时,直接到下一个循环

                }else {

                   
usleep
((DEFAULTFRAMEINTERVAL - (curTime-lastTime)*1000) *1000);

                }

               NSLog(@"wait for data . in caching...");

            }else {                 

               
NSData
*fullPurePacketData = (NSData *)[mediaDicobjectForKey:C_FULLPACKETDATA];

               
UIImage
*showImage = [videoPlayStream decodeWithMediaPureData:fullPurePacketData];

//                NSLog(@"after decodeWithMediaPureData:%@", [dateFormatter stringFromDate:[NSDate date]]);

               
if
(showImage == nil) {

                   //不做continue,
在结尾处可以使得mediaDic被释放

                }else {                       

                    curTime = [NSDatetimeIntervalSinceReferenceDate];                    

                     usleep((playInterval -MICROSECONDSFORPLAYCACHE - (curTime-lastTime)*1000)
*1000);//
等待缓冲状态

                               

                    [selfperformSelectorOnMainThread:@selector(OriginimageArrival:)withObject:showImagewaitUntilDone:YES];

                }

                

                //记录这帧的时间戳,以及这帧的播放时间点作为下次参照依据,作为上次刷屏时间

                lastTime = [NSDatetimeIntervalSinceReferenceDate]; 

                lastFrameTimeStamp = purePacketTimeStamp;

                [mediaDicrelease];

            }

            

            [whilePoolrelease];

        }

    }

    [videoPlayStreamrelease];

    

    [decodeThreadPoolrelease];

}

<smking:现在看来, 这段代码应该改成 NSRunloop的方式来使用, 就会降低CPU的时间片消耗>

抱歉!评论已关闭.