ios - 使用委托(delegate)清理数组

标签 ios objective-c delegation

我制作了一个 AR 应用程序,可以识别图像并在 AlertView 中显示识别出的对象。在 AlertView 中,我有 2 个按钮:添加和取消,我使用 UIAlertViewDelegate 来了解用户按下了哪个按钮。如果用户按下添加按钮,识别的对象将存储在一个数组中。我将这个数组传递给另一个 ViewController,我在其中设置了一个 TableView。在这个 TableView 的底部有一个“支付”按钮,可以转到另一个 ViewController,我在其中显示识别出的对象的总价。在最后一个 ViewController 中,我可以按下一个按钮来支付我使用 AR 选择的对象。现在,当我按下此按钮时,应用程序会关闭此 ViewController 并返回到第一个 ViewController,但我存储 AR 识别出的对象的数组已满。要删除这个数组的内容,我认为最好的方法是使用委托(delegate)方法,所以我这样做了:

PaymentViewController.h

#import <UIKit/UIKit.h>

@protocol PaymentViewControllerDelegate;

@interface PaymentViewController : UIViewController
@property (strong, nonatomic) IBOutlet UILabel *labelTotal;
- (IBAction)buttonClosePaymentVC:(id)sender;

- (IBAction)buttonPay:(id)sender;

@property(nonatomic,strong)NSString *total;

@property(assign) id<PaymentViewControllerDelegate> delegate;

@end

@protocol PaymentViewControllerDelegate <NSObject>

- (void)cleanReportArray;

@end

PaymentViewController.m

#import "PaymentViewController.h"

@interface PaymentViewController () <UIAlertViewDelegate>

@end

@implementation PaymentViewController
@synthesize delegate = _delegate;

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.labelTotal.text = self.total;
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (IBAction)buttonClosePaymentVC:(id)sender {
    [self dismissViewControllerAnimated:YES completion:nil];
}

- (IBAction)buttonPay:(id)sender {
    NSString *pay = [NSString stringWithFormat:@"Stai per pagare %@, procedi?", self.total];
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"HelloMS" message:pay delegate:self cancelButtonTitle:@"Si" otherButtonTitles:@"No", nil];
    [alert show];
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
    if (buttonIndex == 0) {
        // Procedura per il pagamento e cancellazione del file plist
        NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
        NSString *documentsDirectory = [paths objectAtIndex:0];
        NSString *path = [documentsDirectory stringByAppendingPathComponent:@"objects.plist"];
        NSError *error;
        if (![[NSFileManager defaultManager]removeItemAtPath:path error:&error]) {
            NSLog(@"Errore: %@", error);
        }
        __weak UIViewController *vcThatPresentedCurrent = self.presentingViewController;
        [self dismissViewControllerAnimated:YES completion:^{
            [vcThatPresentedCurrent dismissViewControllerAnimated:YES completion:nil];
        }];
        [self.delegate cleanReportArray];
    }
    if (buttonIndex == 1) {
        // Non deve far nulla: fa scomparire l'UIAlertView
    }
}

在这里,我向您发布将使用委托(delegate)的类的方法:

ScannerViewController.m 的接口(interface)

@interface ScannerViewController () <MSScannerSessionDelegate, PaymentViewControllerDelegate, UIActionSheetDelegate, UIAlertViewDelegate>
@property (weak) IBOutlet UIView *videoPreview;
- (IBAction)stopScanner:(id)sender;
@end

ViewDidLoad 中,我插入了以下行:

PaymentViewController *pay = [[PaymentViewController alloc]init];
[pay setDelegate:self];

ScannerViewController.m 中,我实现了在 PaymentViewController.h 中声明的方法:

- (void)cleanReportArray {
    [arrayObjectAdded removeAllObjects];
}

我在我的 iPhone 上测试了我的应用程序,应用程序工作正常,直到我尝试支付我用相机扫描的对象,事实上,我尝试支付对象,但它没有清除我存储对象的数组扫描。 我的代码有什么问题?我使用了网络上的教程来更好地理解委托(delegate)方法的工作原理。希望您能帮我解决这个问题,谢谢

更新: 在这里我将发布我的 ScannerViewController 代码:

ScannerViewController.h

#import <UIKit/UIKit.h>

@interface ScannerViewController : UIViewController

@end

ScannerViewController.m

#import "ScannerViewController.h"
#import "PaymentViewController.h"
#import "ReportViewController.h"
#import "MSScannerSession.h"
#import "MSResult.h"
#import "XmlReader.h"

static int kMSScanOptions = MS_RESULT_TYPE_IMAGE    |
                            MS_RESULT_TYPE_EAN8     |
                            MS_RESULT_TYPE_EAN13;

@interface ScannerViewController () <MSScannerSessionDelegate, PaymentViewControllerDelegate, UIActionSheetDelegate, UIAlertViewDelegate>
@property (weak) IBOutlet UIView *videoPreview;
- (IBAction)stopScanner:(id)sender;
@end

@implementation ScannerViewController {
    MSScannerSession *_scannerSession;
    NSString *nameOfObjectScanned;
    XmlReader *reader;
    NSMutableArray *arrayObjectAdded;
}

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        _scannerSession = [[MSScannerSession alloc] initWithScanner:[MSScanner sharedInstance]];
        [_scannerSession setScanOptions:kMSScanOptions];
        [_scannerSession setDelegate:self];

    }
    return self;
}

- (void)session:(MSScannerSession *)scanner didScan:(MSResult *)result {
    if (!result) {
        return;
    }
    [_scannerSession pause];

    NSString *resultStr = nil;

    if (result) {
        switch ([result getType]) {
            case MS_RESULT_TYPE_IMAGE:
                resultStr = [NSString stringWithFormat:@"Immagine trovata: %@", [result getValue]];
                break;
            case MS_RESULT_TYPE_EAN8:
            case MS_RESULT_TYPE_EAN13:
                resultStr = [NSString stringWithFormat:@"EAN trovato: %@", [result getValue]];
                break;
            default:
                break;
        }
    }
    dispatch_async(dispatch_get_main_queue(), ^{
        UIActionSheet *asView = [[UIActionSheet alloc]initWithTitle:resultStr delegate:self cancelButtonTitle:@"OK" destructiveButtonTitle:nil otherButtonTitles:nil, nil];
        asView.actionSheetStyle = UIActionSheetStyleBlackTranslucent;
        [asView showInView:self.view];
        [self addObjectToList:resultStr];
    });

}

- (void)addObjectToList:(NSString *)objectName {
    // Ricerca dell'oggetto
    NSString *object = [objectName substringFromIndex:18];
    if ([object isEqualToString:@"Binario_con_coppia"]) {
        [self showAlert:object];
    }
    if ([object isEqualToString:@"Dadi_colorati"]) {
        [self showAlert:object];
    }
    if ([object isEqualToString:@"Dadi_rossi"]) {
        [self showAlert:object];
    }
    if ([object isEqualToString:@"Bici_da_corsa"]) {
        [self showAlert:object];
    }
}

- (void)showAlert:(NSString*)name {
    name = [name stringByReplacingOccurrencesOfString:@"_" withString:@" "];
    nameOfObjectScanned = name;
    NSString *message = [NSString stringWithFormat:@"Ho riconosciuto questo oggetto: %@, vuoi aggiungerlo al carrello?", name];
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"HelloMS" message:message delegate:self cancelButtonTitle:@"Aggiungi" otherButtonTitles:@"Annulla", nil];
    [alert show];
}

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
    if (buttonIndex == 0) {
        NSLog(@"Aggiungi");
        for (int i = 0; i < [reader.objArray count]; i++) {
            if ([[reader.objArray[i]objectForKey:@"name"] isEqualToString:nameOfObjectScanned]) {
                // Salvo il nome dell'oggetto trovato, il prezzo e la descrizione
                NSString *name = [reader.objArray[i]objectForKey:@"name"];
                NSString *desc = [reader.objArray[i]objectForKey:@"desc"];
                NSString *price = [reader.objArray[i]objectForKey:@"price"];
                NSDictionary *newObjectAdded = [[NSDictionary alloc]init];
                newObjectAdded = @{@"name": name,
                                   @"desc": desc,
                                   @"price": price};
                [arrayObjectAdded addObject:newObjectAdded];
            }
        }
    } else {
        NSLog(@"Annulla");
    }
}

- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
    [_scannerSession resume];
}


- (void)viewDidLoad
{
    [super viewDidLoad];

    arrayObjectAdded = [[NSMutableArray alloc]init];
    CALayer *videoPreviewLayer = [self.videoPreview layer];
    [videoPreviewLayer setMasksToBounds:YES];

    CALayer *captureLayer = [_scannerSession previewLayer];
    [captureLayer setFrame:[self.videoPreview bounds]];

    [videoPreviewLayer insertSublayer:captureLayer below:[[videoPreviewLayer sublayers] objectAtIndex:0]];
    reader = [[XmlReader alloc]init];
    [reader parseXml];
    [_scannerSession startCapture];
    PaymentViewController *pay = [[PaymentViewController alloc]init];
    [pay setDelegate:self];
}

- (void)cleanReportArray {
    [arrayObjectAdded removeAllObjects];
}

- (void)dealloc {
    [_scannerSession stopCapture];
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (IBAction)stopScanner:(id)sender {
    ReportViewController *reportVC = [[ReportViewController alloc]initWithNibName:@"ReportViewController" bundle:nil];
    reportVC.reportArray = arrayObjectAdded;
    [reportVC setModalTransitionStyle:UIModalTransitionStyleFlipHorizontal];
    [self presentViewController:reportVC animated:YES completion:nil];
}

@end

为了识别图片,我正在使用这个 AR SDK .我希望你能帮助我了解我的问题出在哪里

最佳答案

你的问题是在 viewDidLoad 中你有代码:

PaymentViewController *pay = [[PaymentViewController alloc]init];
[pay setDelegate:self];

这是您在该方法中做的最后一件事。因此,您创建并设置委托(delegate)的 PaymentViewController 实例会立即被销毁(通过 ARC)。

您需要修改您的代码,以便在屏幕上显示的 PaymentViewController 的实际实例上调用 setDelegate:,因为这是需要使用委托(delegate)(它从警报 View 接收回调)。

关于ios - 使用委托(delegate)清理数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19490968/

相关文章:

ios - 识别禁用的 UIButton 上的点击或手势事件

objective-c - iOS:NSString变量返回null

iphone - 自动更改到下一个 ViewController

javascript - JQuery 类添加/删除不起作用(使用未知的委托(delegate))

ios - 使用 ARC 将模态视图 Controller 的委托(delegate)设置为 nil

ios - 如何通过点击来选择和取消选择行

ios - NSJSONSerialization 崩溃的应用程序

iphone - 使用 Plist 中的数据在 map 上显示多个 Pin 图

C++ 可变参数模板委托(delegate)周期错误

ios - Storyboard选项在 Xcode v7.0 中对 iPad 不可见