2012-02-29 31 views
1

我想知道如何将对象作为参数传递给目标C.如您所见,在我的代码中,Obj1 * myObj1超出了btnIncrementObj1方法的作用域。我如何把它放在范围内?我在想,有一种方法可以将类的实例设置为静态。您可以看到,我只希望myObj1在按下按钮时实例化,而不是在视图加载时实例化。目标C中的类的全局实例C

有没有办法让Obj1变成静态的,还是给它一个全局范围?

- (IBAction)btnCreateObj1:(UIButton *)sender 
{ 
    Obj1 * myObj1 = [[Obj1 alloc] init]; 

    int intVal = [self.textField.text intValue]; 

    [myObj1 increment:intVal]; 

    [myObj1 restring:@"orig string 1"]; 

    NSString * newLabel = [self.labelObject1.text stringByAppendingFormat:@"value:%d string:%@",myObj1.value,myObj1.someString]; 

    self.labelObject1.text = newLabel; 
} 

- (IBAction)btnIncrementObj1:(UIButton *)sender 
{ 
    //-I want to increment myObj1.value by [self.textField.text intValue] 
} 

回答

1

好的,这是我的回答。这扩大了Lanc给出的。

首先,您需要确定myObj1的范围应该是什么。你想每个实例的类或整个应用程序只有一个。如果它是每个类的实例,则创建一个实例变量并拥有一个按需创建它的属性。例如

@interface MyViewController : UIViewController 

@property (nonatomic, readonly, retain) Obj1* myObj1; 

// other stuff 

@end 

@implementation MyViewController 
{ 
@private 
    Obj1* myObj1; 
} 

-(Obj1*) myObj1 
{ 
    @synchronized(self) // if you know you are single threaded you can omit the @synchronized block 
    { 
     if (myObj1 == nil) 
     { 
      myObj1 = [[Obj1 alloc] init]; 
     } 
    } 
    return myObj1; 
} 

- (IBAction)btnCreateObj1:(UIButton *)sender 
{ 
    [[self myObj1] increment:intVal]; 

    [[self myObj1] restring:@"orig string 1"]; 

    NSString * newLabel = [self.labelObject1.text stringByAppendingFormat:@"value:%d string:%@",myObj1.value,myObj1.someString]; 

    self.labelObject1.text = newLabel; 
} 

- (IBAction)btnIncrementObj1:(UIButton *)sender 
{ 
    [[self myObj1] increment: [self.textField.text intValue]]; 
} 

如果你需要一个单身(即仅针对每个程序对象),你可以使用一个静态变量按照wizH的答案,但我更喜欢使用的方法来访问它。所以,下面的工作:

@interface MyViewController : UIViewController 

@property (nonatomic, readonly, retain) Obj1* myObj1; 

// other stuff 

@end 

@implementation MyViewController 

-(Obj1*) myObj1 
{ 
    static Obj1* myObj1 = nil; // instance var moved to be a static variable 
    @synchronized([MyViewController class) // if you know you are single threaded you can omit the @synchronized block 
    { 
     if (myObj1 == nil) 
     { 
      myObj1 = [[Obj1 alloc] init]; 
     } 
    } 
    return myObj1; 
} 

- (IBAction)btnCreateObj1:(UIButton *)sender 
{ 
    [[self myObj1] increment:intVal]; 

    [[self myObj1] restring:@"orig string 1"]; 

    NSString * newLabel = [self.labelObject1.text stringByAppendingFormat:@"value:%d string:%@",myObj1.value,myObj1.someString]; 

    self.labelObject1.text = newLabel; 
} 

- (IBAction)btnIncrementObj1:(UIButton *)sender 
{ 
    [[self myObj1] increment: [self.textField.text intValue]]; 
} 

注意,已经改变的唯一事情是如何为类的API是满意的方式。没有使用API​​的代码必须改变。

+0

非常感谢你。令人惊讶的伟大答案。 – iggy2012 2012-02-29 21:46:09

1

如果您想在整个类中访问变量,请将其设置为类成员。

+0

将这个代码是什么对象? – iggy2012 2012-02-29 10:22:51

0

您应该创建对象后,右侧的

@implementation 

在这里,你可以创建它作为一个静态对象:

static Obj1* _myObj1 = nil; 

从这里,你可以从其他类访问它像这样:

[Obj1 myObj1].property 
+0

即使我的目标是仅在按下按钮时进行实例化,这是否是常见做法? – iggy2012 2012-02-29 09:51:56

+0

是的。这几乎在我所有共享对象的应用程序中完成。如果它解决了你的问题,请评价为最佳答案。 – wizH 2012-02-29 10:03:14

+0

@ iggy2012:不,这不是一种常见的做法。您可能想在上面的示例中创建一个类成员。全局对象几乎总是一个坏主意。 – JeremyP 2012-02-29 10:08:07

0

您的.h文件应导入您想要保留的对象并在该类中创建该对象的成员。 它看起来像这样。

#import "Obj1.h"; 

@interface MyViewController : UIViewController{ 
    Obj1 * myObj1; 
} 

我不会在IBAction方法中初始化一个类变量,但您可以这样做。 在创建的按钮中,您可以保留相同的代码。但在其他方法中,只需检查是否创建了myObj1。

- (IBAction)btnIncrementObj1:(UIButton *)sender 
{ 
    if(myObj1){ 
     //Handle the increment. 
    }else{ 
     //Handle what to do if you haven't clicked the other button before this one. 
    } 
} 

而对于好的内存管理应该释放的dealloc

-(void) dealloc{ 
    if(myObj1){ 
     [myObj1 release]; 
    } 
    [super dealloc]; 
}