gpt4 book ai didi

ios - 使用 GCD 按顺序发送邮件

转载 作者:可可西里 更新时间:2023-11-01 06:24:31 26 4
gpt4 key购买 nike

每当用户点击图片时,图像应该发送到他的邮件。我希望这在后台发生,所以我使用 SKPSMTPMessage。如果用户在发送/上传上一张图片之前单击一张图片,我会收到错误消息。我想我会使用 GCD 来序列化它,但我无法解决它。

- (IBAction)snapStillImage:(id)sender
{

//code after taking the picture
if([uploadMethod isEqualToString:@"Mail"]){
time_t unixTime = (time_t) [[NSDate date] timeIntervalSince1970];
NSString *timestamp=[NSString stringWithFormat:@"%ld",unixTime];
NSData *jpgData = UIImageJPEGRepresentation(image, 0.5);
[jpgData writeToFile:[self documentsPathForFileName:timestamp] atomically:YES];
[self.imagesArray addObject:timestamp];
[self sendMail];

}


-(void)sendMail{
dispatch_queue_t myFifoQueue = dispatch_queue_create("com.xxxx.uploadpictures",DISPATCH_QUEUE_SERIAL);
if(!self.imagesArray.count == 0){
for(NSString *str in self.imagesArray){
dispatch_async(myFifoQueue,^{
[self sendMailWith:str];
});
}
}
}

最佳答案

一些观察:

  1. 正如 Andrey 指出的那样,您只想创建一个队列,而不是每次都创建一个新队列。

  2. 鉴于 SKPSMTPMessage 异步操作,如果您希望它们按顺序运行,您需要重构此代码,以便下一个请求不会开始,直到先前的异步请求是完毕。典型的解决方案是:

    • 使用操作队列(NSOperationQueue)。

    • 将您的异步发送请求包装在并发的 NSOperation 子类中。您可以将 NSOperation 设置为 SKPSMTPMessage 对象的 delegate,并在 messageSentmessageFailed 方法,您将完成操作(发布必要的 isFinishedisExecuting 通知)。

      请参阅 Operation Queues为并发执行配置操作部分并发编程指南章节了解更多信息。

    • 确保配置队列或操作,以便按顺序发送它们(例如,将操作队列的 maxConcurrentOperationCount 设置为 1 以使其成为串行队列)。


为了说明,您将定义一个操作队列:

@property (nonatomic, strong) NSOperationQueue *mailQueue;

您只需配置一次:

self.mailQueue = [[NSOperationQueue alloc] init];
self.mailQueue.maxConcurrentOperationCount = 1;

然后您将向该队列添加邮件请求:

[self.mailQueue addOperation:[[SendEmailOperation alloc] initWithTo:@"rob@example.com"
subject:@"title"
body:@"body"
path:pathToImage]];

所以,有趣的问题是这个 SendMailOperation 可能看起来像什么:

//  SendEmailOperation.h

#import "ConcurrentOperation.h"

@interface SendEmailOperation : ConcurrentOperation

@property (nonatomic, copy) NSString *to;
@property (nonatomic, copy) NSString *subject;
@property (nonatomic, copy) NSString *body;
@property (nonatomic, copy) NSString *path;

- (instancetype)initWithTo:(NSString *)to subject:(NSString *)subject body:(NSString *)body path:(NSString *)path;

@end

//  SendEmailOperation.m

#import "SendEmailOperation.h"
#import "SKPSMTPMessage.h"

@interface SendEmailOperation () <SKPSMTPMessageDelegate>

@end

@implementation SendEmailOperation

- (instancetype)initWithTo:(NSString *)to subject:(NSString *)subject body:(NSString *)body path:(NSString *)path
{
self = [super init];
if (self) {
self.to = to;
self.subject = subject;
self.body = body;
self.path = path;
}
return self;
}

- (void)main
{
SKPSMTPMessage *message = [self createMessage]; // configure your message like you are now
message.delegate = self;
[message send];
}

- (SKPSMTPMessage *)createMessage
{
SKPSMTPMessage *message = [[SKPSMTPMessage alloc] init];

// configure this message like you are now, picking up the various class properties
// (e.g. to, subject, body, etc.).

return message;
}

#pragma mark - SKPSMTPMessageDelegate

-(void)messageSent:(SKPSMTPMessage *)message
{
[self completeOperation];
}

-(void)messageFailed:(SKPSMTPMessage *)message error:(NSError *)error
{
NSLog(@"%s: %@", __PRETTY_FUNCTION__, error);

[self completeOperation];
}

@end

并且,最后,并发操作子类的核心被隐藏在这个 ConcurrentOperation 类中。一旦你开始使用并发操作,你会发现自己经常使用这种模式,所以这个类让你不必不断地重新实现并发操作子类的东西:

//  ConcurrentOperation.h

#import <Foundation/Foundation.h>

@interface ConcurrentOperation : NSOperation

- (void)completeOperation;

@end

//  ConcurrentOperation.m

#import "ConcurrentOperation.h"

@interface ConcurrentOperation ()

@property (nonatomic, getter = isFinished, readwrite) BOOL finished;
@property (nonatomic, getter = isExecuting, readwrite) BOOL executing;

@end

@implementation ConcurrentOperation

@synthesize finished = _finished;
@synthesize executing = _executing;

- (id)init
{
self = [super init];
if (self) {
_finished = NO;
_executing = NO;
}
return self;
}

- (void)start
{
if ([self isCancelled]) {
self.finished = YES;
return;
}

self.executing = YES;

[self main];
}

- (void)completeOperation
{
self.executing = NO;
self.finished = YES;
}

#pragma mark - NSOperation methods

- (BOOL)isConcurrent
{
return YES;
}

- (void)setExecuting:(BOOL)executing
{
if (_executing != executing) {
[self willChangeValueForKey:@"isExecuting"];
_executing = executing;
[self didChangeValueForKey:@"isExecuting"];
}
}

- (void)setFinished:(BOOL)finished
{
if (_finished != finished) {
[self willChangeValueForKey:@"isFinished"];
_finished = finished;
[self didChangeValueForKey:@"isFinished"];
}
}

@end

我知道这看起来很像,但是一旦您的工具带中有了 ConcurrentOperation(或类似的东西),您就会发现创建并发操作真的很容易,而且非常有用每当您想按顺序(或与某些特殊依赖项并发)执行一系列异步任务时。

关于ios - 使用 GCD 按顺序发送邮件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25426392/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com