【问题标题】:Clean array by using delegate使用委托清理数组
【发布时间】:2013-10-21 09:39:39
【问题描述】:

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

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
    }
}

在这里,我将使用委托的类的方法发布给您:

ScannerViewController.m 的接口

@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 上测试了我的应用程序,该应用程序运行良好,直到我尝试支付我通过相机扫描的对象,事实上,我尝试支付对象,但它没有清理我存储对象的数组扫描。 我的代码有什么问题?我使用网络上的教程来更好地理解委托方法的工作原理。希望能帮我解决这个问题,谢谢

更新: 在这里我将发布我的 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。我希望你能帮助我了解我的问题在哪里

【问题讨论】:

  • 您在调用cleanReportArray 时是否进行了调试以检查是否设置了委托?
  • 我现在检查了一下:我在这一行放了一个断点:[pay setDelegate:self];,当我运行应用程序时,我看到在“支付”下设置了委托...
  • 你什么时候来使用委托?您的代码通常看起来是正确的,因此您很有可能将委托设置在错误的对象上或类似的东西上......
  • 现在我用 ScannerViewController 的所有代码编辑了我的问题,希望你能帮助我
  • 也许我发现了一些奇怪的东西:当我按下按钮支付我的对象时,我调用了委托方法,但是当我在那里放置一个断点时,我看到 delegate 的值没有改变,它仍然是0x0,所以我猜那里有问题对吧?我猜想当我使用这条指令时委托方法的值应该改变:[self.delegate cleanReportArray];

标签: ios objective-c delegation


【解决方案1】:

你的问题是viewDidLoad你有代码:

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

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

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

【讨论】:

  • 谢谢,我现在就试试!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-11-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-07
相关资源
最近更新 更多