【问题标题】:Using Arrays in Singleton Class to Pass Data Between View Controllers IOS?在 Singleton 类中使用数组在视图控制器 IOS 之间传递数据?
【发布时间】:2012-04-06 00:47:43
【问题描述】:

我一直在寻找表格视图和单例类,但找不到任何解决方案,所以我在这里。

当用户选择一行时,我在视图控制器中有一个表格视图

这是我的单例类代码:

#import <Foundation/Foundation.h>


@interface DataController : NSObject {
    NSArray* standLoc;
}

@property (readonly)NSArray* standLoc; // stand location 

+(DataController*)sharedInstance;

@end


#import "DataController.h"

@implementation DataController

@synthesize standLoc;

+(DataController*)sharedInstance
{
    static DataController* sharedInstance = nil;
    if (!sharedInstance)
    {
        sharedInstance = [[DataController alloc]init];
    }
    return sharedInstance;
}

@end

那么我应该如何将数据传递给我尝试遵循的单例类中的数组,

- (void) tableView: (UITableView *) tableView didSelectRowAtIndexPath: (NSIndexPath *) indexPath {

    StartHuntViewController *startHuntController = [[StartHuntViewController alloc] initWithNibName:@"StartHuntView" bundle:nil];

    DataController* sharedSingleton = [DataController sharedInstance];
    sharedSingleton = [stands objectAtIndex:indexPath.row];

    startHuntController.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
    [self presentModalViewController:startHuntController animated:YES];;


    [startHuntController release];
    startHuntController =nil;
}

在调试中,我可以看到所选项目在 sharedSingleton 中,但我如何将其传递给 NSArray* standLoc?

编辑


所以我已经编辑了我的代码,现在它可以在多个控制器视图中正常工作

我的单身 .m 和 .h :

#import <Foundation/Foundation.h>


@interface DataController : NSObject {
    NSString* standLoc;
}

@property (nonatomic,retain)NSString* standLoc; // stand location 

+(DataController*)sharedInstance;
-(void) setData: (NSString *) data;

@end
#import "DataController.h"


@implementation DataController


static DataController* sharedInstance = nil;

@synthesize standLoc;

+(DataController*)sharedInstance
{

    @synchronized (self) { //this ensure this methods will not be called at the same time..
        if(sharedInstance == nil){
            [[self alloc] init];
        }
    }
    return sharedInstance;
}
+(id) allocWithZone:(NSZone *)zone{
    @synchronized (self){
        if (sharedInstance == nil) {
            sharedInstance = [super allocWithZone:zone];
            return sharedInstance;
        }
    }
    return nil;
}
-(id)copyWithZone:(NSZone *)zone{ // incase if we want to copy our singleton instance
    return self;
}
//to protect singleton from deallocation, we need to override some functions of memory allocation
-(id) retain {
    return self;
}

-(id) autorelease{
    return self;
}
-(NSUInteger ) retainCount{
    return NSUIntegerMax;
}

-(id) init{ // lets set the default data in it
    @synchronized (self){
        [super init];
        standLoc = [[NSString alloc] initWithString:@"Stand Loc"];//for performance, as we expect 5 digits from server, it's size was set to another 5 digits..
        return self;
    }
}
-(void) setData: (NSString *) data{ // this is the function to set static data which is the member of the class, reaching data will be allowed with this method
    @synchronized (self){
        if (standLoc != data) {
            [standLoc release];
            standLoc = [data retain];
        }
    }
}
-(NSString *) standLoc{
    @synchronized(self){
        return standLoc;
    }
}

将数据传递给单例:

DataController* sharedSingleton = [DataController sharedInstance];
    NSString* transfer = [stands objectAtIndex:indexPath.row];
    [sharedSingleton setData:transfer];

【问题讨论】:

    标签: ios uitableview singleton nsarray


    【解决方案1】:
    • 如果要从其他类更新standLoc,请勿将其设为只读。
    • 如果要从“stands”中传递一个对象,为什么要将 standLoc 设为一个数组?
    • 你想要的那种语法(解决以上两点后)是:

      DataController* sharedSingleton = [DataController sharedInstance];

      sharedSingleton.standLoc = // 无论数据元素是什么,都应该在单例中;

    【讨论】:

      【解决方案2】:

      为什么需要单例?如果您只是将数据直接从一个视图控制器传递到下一个视图控制器,您的代码将更简单、更易于维护。听起来您正在使用导航控制器,因此当点击表格中的单元格时,表格的视图控制器可以推送新的细节控制器,如下所示:

      - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
          DetailViewController *detailController = [[DetailViewController alloc] initWithNibName:nil bundle:nil];
          detailViewController.data = [tableData objectAtIndex:[indexPath row]];
          [self.navigationController pushViewController:detailController animated:YES];
      }
      

      【讨论】:

      • 问题是我有多个视图控制器而不仅仅是两个,如果我将数据从任何视图传递到主视图并导航到另一个视图控制器然后再次返回到主视图,我看到数据已经丢失,所以我需要一个将数据保存在我的主视图控制器中的解决方案,所以我认为单例模式就是答案
      【解决方案3】:

      你为什么使用@同步?

      (在 iOS 上很少使用..) 无论如何,如果您使用(非原子)然后@synchronized,这似乎有点奇怪..

      让我们的 Apple 编译器做得更好:

      (https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/EncapsulatingData/EncapsulatingData.html)

      属性默认是原子的 默认情况下,Objective-C 属性 是原子的:

      @interface XYZObject : NSObject @property NSObject *隐式原子对象; // 默认原子 @property (atomic) NSObject *explicitAtomicObject; // 显式标记为原子 @end 这意味着合成访问器确保一个值是 始终由 getter 方法完全检索或通过 setter 方法,即使访问器同时从 不同的线程。

      最后一点:正如 Apple 所说,使用锁、原子等,并不能保证不会对来自不同线程的数据进行深度访问:

      如果你有一个数组并且你用原子/同步保护它(它的引用..),你保护对它的访问,而不是对包含的对象。 (您必须非常小心地手动锁定......可能会发生竞争情况......)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-12-28
        • 1970-01-01
        • 2011-07-09
        • 1970-01-01
        相关资源
        最近更新 更多