Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/111.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
多读ios_Ios_Multithreading_Alassetslibrary - Fatal编程技术网

多读ios

多读ios,ios,multithreading,alassetslibrary,Ios,Multithreading,Alassetslibrary,我的应用程序的功能是在两台设备之间传输图片 用户可以选择许多图片发送。但是由于发送过程需要时间,所以现在我只是将用户从照片库中选择的尚未发送的图片放入一个数组中 我现在的问题是,如果用户一次选择太多图片,我的应用程序将突然终止。我现在的解决方案是,如果用户一次选择太多图片,我只会在一些图片上做标记,但将它们留在照片库中,同时也将它们放入阵列中。然后我有另一个线程在发送操作发生的同时从库中加载图片。因此,我的观点是,我怀疑一次将这么多图片放入阵列是应用程序终止的原因,所以我想缓存一些图片,然后将其

我的应用程序的功能是在两台设备之间传输图片

用户可以选择许多图片发送。但是由于发送过程需要时间,所以现在我只是将用户从照片库中选择的尚未发送的图片放入一个数组中

我现在的问题是,如果用户一次选择太多图片,我的应用程序将突然终止。我现在的解决方案是,如果用户一次选择太多图片,我只会在一些图片上做标记,但将它们留在照片库中,同时也将它们放入阵列中。然后我有另一个线程在发送操作发生的同时从库中加载图片。因此,我的观点是,我怀疑一次将这么多图片放入阵列是应用程序终止的原因,所以我想缓存一些图片,然后将其他一些图片留在磁盘中,我的代码:

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
    if(alertView.tag == 100)
    {
        if (buttonIndex == 1)
        {
            inArray = YES;
            NSLog(@"---------%d",[self.imageArr count]);
            if ([self.imageArr count] < kCachedImages) {
                [self.imageArr addObject:thisImageObj];
                [thisImageObj release];
            }
            else
            [self.imageURLArr addObject:photoURL];

            if(!isSending)
            {
                currentPos = -1;
                [self sendImage];
            }
            [sndTableView reloadData];
        }
        else if (buttonIndex == 2)
        {
            if (inArray) {
                if ([self.imageArr count] < kCachedImages) {
                    [self.imageArr addObject:thisImageObj];
                    [thisImageObj release];
                }else {
                    [self.imageURLArr addObject:photoURL];
                }
            }else {
                [self.imageArr addObject:thisImageObj];
            }

           if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad){
               [self.popOverView dismissPopoverAnimated:YES];
            }
           else {
               [self dismissModalViewControllerAnimated:YES];
           }


            [sndTableView reloadData];
            if(!isSending)
            {
                currentPos = -1;
                [self sendImage];
            }
        }

    }

}


- (void)sendImage
{
    if(![self.imageArr count])
    {
        [[UIApplication sharedApplication] setIdleTimerDisabled:NO];
        isSending = NO;
        [self.navigationItem setHidesBackButton:NO animated:YES];
        return; //end of all sending
    }


    NSMutableData *toBeSend = [NSMutableData dataWithCapacity:sizeof(packetHeader)+kBuffer];
    imageObj *imgObj;
    if ([self.imageArr count]) {
        imgObj = [[self.imageArr objectAtIndex:0]retain];
    }

  //here created another thread to load pics from library  
    if ([self.imageURLArr count] > 0) {
                         [NSThread detachNewThreadSelector:@selector(load) toTarget:self withObject:nil];
    }


    packetHeader header;
    header.magic = 0x5577ACAC;
    header.seq = currentSeq++;

    if(currentPos < 0) //first packet
    {
        UIImage *img = [UIImage imageWithData:imgObj.pimage];
        self.currentSendingImg.image = img;

        //thumbnail
        img = [TransferViewController imageWithImage:img scaledToSize:CGSizeMake(70, 70)];
        NSData *data = UIImageJPEGRepresentation(img, 0.5);

        header.command = 16;
        header.commandData1 = imgObj.imageSize;
        header.commandData2 = (imgObj.imageWidth<<16) + imgObj.imageLength;
        header.commandData3 = [data length];
//      NSLog(@"thumbnail data length = %u", header.commandData3);
        [toBeSend appendData:[NSData dataWithBytes:&header length:sizeof(packetHeader)]];
        [toBeSend appendData:data];
        currentPos = 0;
        isSending = YES;
        [[UIApplication sharedApplication] setIdleTimerDisabled:YES];
        [self.navigationItem setHidesBackButton:YES animated:YES];
    }
    else
    {
        if(currentPos + kBuffer < imgObj.imageSize)
        {
            header.command = 19;
            header.commandData1 = kBuffer;
            [toBeSend appendData:[NSData dataWithBytes:&header length:sizeof(packetHeader)]];
            NSRange r;
            r.location = currentPos;
            r.length = kBuffer;
            [toBeSend appendData:[imgObj.pimage subdataWithRange:r]];
            currentPos += kBuffer;
        }
        else
        {//last packet
            header.command = 17;
            header.commandData1 = imgObj.imageSize - currentPos;
            [toBeSend appendData:[NSData dataWithBytes:&header length:sizeof(packetHeader)]];
            NSRange r;
            r.location = currentPos;
            r.length = header.commandData1;
            [toBeSend appendData:[imgObj.pimage subdataWithRange:r]];
            currentPos = -1;
            if ([self.imageArr count]) {
                [self.imageArr removeObjectAtIndex:0];
            }
            [self.sndTableView reloadData];
        }
    }

    [manager sendPacket:toBeSend];
    self.sendingProgess.progress = (float)currentPos / (float)imgObj.imageSize;

    [imgObj release];
}


- (void)load 
{


    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

    if (![imageURLArr count]) {
        return;
    }        
    int imageSum = [imageURLArr count];

        NSURL *path = [self.imageURLArr objectAtIndex:0] ;

        ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
        [library assetForURL:path resultBlock:^(ALAsset *asset)
         {
             ALAssetRepresentation *representation = [asset defaultRepresentation];
             CGImageRef ref = [representation fullResolutionImage];
             if (ref != nil) {
                 omg = [UIImage imageWithCGImage:ref];
                 [omg retain];
             }

         }
                failureBlock:^(NSError *error)
         {
             // error handling
         }];
        [library release];

        if (omg) {
            NSData *data = UIImageJPEGRepresentation(omg, kcompressionQuality);
            thisImageObj = [imageObj alloc];
            thisImageObj.imageSize = [data length];
            thisImageObj.imageWidth = omg.size.width;
            thisImageObj.imageLength = omg.size.height;
            thisImageObj.pimage = data;
            [omg release];
        }
        else {
            return;
        }


    imageSum--;

    if ([self.imageURLArr count]) {
        [self.imageURLArr removeObjectAtIndex:0];
    }

    [self.imageArr addObject:thisImageObj];
    [thisImageObj release];

    [NSThread sleepForTimeInterval:1.0];

    [pool release];

}

但是其他线程中的方法现在起作用了,终止的问题仍然存在,所以有人可以给我一些建议,告诉我怎么做,或者我根本不需要其他线程。首先,您使用的是detachNewThreadSelector:toTarget:withObject:,这几乎从来都不是正确的工具。这可以生成无限数量的线程。这可能不是让你崩溃的原因,但这是一种非常危险的做法。更好的解决方案如下:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0), ^{
  [self load];
};
这将正确管理线程池

您的主要问题是,您访问IVAR时没有任何锁定。NSMutableArray不是线程安全的。你不能只在任何线程上修改它。GCD在这方面也有帮助。Mike Ash写了一篇很好的文章,名为“您可以使用dispatch\u sync进行读取,使用dispatch\u barrier\u async进行写入”


总而言之,确保你真的需要这个背景线程。什么东西装了这么久?当您可以避免线程时,通常应该这样做。

UIImageJPEG表示是您的问题。UIKit和线程是致命的敌人。我试图清理你的文本,但仍然无法说出你的问题是什么。很抱歉,我的问题不够清楚,我有一个可变数组来保存图片,但如果图片太多,应用程序将崩溃,我的解决方案是将一些图片放在此数组中,将其他图片放在库中,然后send和loadimages同时运行,但是在不同的线程中,解决方案不起作用now@CodaFi,UIImageJPEG表示不再要求它在主线程上运行。自iOS4以来,大部分UIKit都可以在后台线程上运行。只能在主线程上运行当前视图上下文中的绘图和一些明确记录的函数。