Objective-C中的单例,用于存储和访问程序范围的变量.几个问题

Jan*_*ann 3 iphone singleton objective-c

我正在使用Apple的MyGizmoClass Singleton类来实现程序范围的"会话变量"并且喜欢它!但是,当我运行"构建和分析"时,它会产生奇怪的结果.也许我的用法是错误的(它可以工作,但它可能因为一个有趣的副作用而起作用).这是一个例子.

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {

    int ct = 0;
    MyGizmoClass *myGizmoClass= [MyGizmoClass sharedManager];
    ct = [[myGizmoClass searchResultsForResortLocation] count];
    [myGizmoClass release];
    NSLog(@"ct: %d",ct);
    return ct;
}
Run Code Online (Sandbox Code Playgroud)

要么

- (void)viewWillAppear:(BOOL)animated {


     // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
     //self.navigationItem.rightBarButtonItem = self.editButtonItem;

    NSMutableString *which_resort = [[NSMutableString alloc] init];
    NSMutableString *category_code = [[NSMutableString alloc] init];
    MyGizmoClass *myGizmoClass= [MyGizmoClass sharedManager];

    ...

    which_resort = [self which_resort_location_are_we_in];

    ... 
    [myGizmoClass setWhich_resort:which_resort];

    int useDebugMode = [myGizmoClass useDebugMode]; 

    ...


    [myGizmoClass release];

    [which_resort release];
    [category_code release];

    [super viewWillAppear:animated];

}
Run Code Online (Sandbox Code Playgroud)

同样,这种用法可能是关闭的,但我认为每个方法我都使用了我必须做的单身人士的价值:

MyGizmoClass *myGizmoClass= [MyGizmoClass sharedManager];
Run Code Online (Sandbox Code Playgroud)

[myGizmoClass release];
Run Code Online (Sandbox Code Playgroud)

但我在Analyze期间收到这些错误:

/Users/jgobble/Documents/ProgramName/Classes/ResortsListViewController.m:495:2一个对象的引用计数不正确减量没有在这一点上由呼叫者/Users/jgobble/Documents/ProgramName/Classes/ResortsListViewController.m资:493:30方法返回一个Objective-C的对象与一个0保留计数(非所属参考)/Users/jgobble/Documents/ProgramName/Classes/ResortsListViewController.m:495:2一个对象的引用计数不正确的减量此时调用者不拥有此权限

现在,请考虑到这一点:我称之为:

MyGizmoClass *myGizmoClass= [MyGizmoClass sharedManager];
Run Code Online (Sandbox Code Playgroud)

在每个方法的开头需要一个"会话变量",然后调用:

[myGizmoClass release];
Run Code Online (Sandbox Code Playgroud)

在该方法结束时返回结果(如果我从该函数返回结果).

这不是我应该这样做的方式吗?

这是分析仪(感谢良好)报告程序错误的唯一问题.我不知道我是否应该忽略它.我不知道我是否在正确的地方打电话.

这是我担心的另一个问题:这是否有效或后续调用*myGizmoClass会搞砸什么?

-(void) function_a {
     MyGizmoClass *myGizmoClass= [MyGizmoClass sharedManager];

     [myGizmoClass setC:1];

     int result_b = [self function_b];

     printf("Addition result is: %d", result_b);

     [myGizmoClass release]
}

-(int) function_b {
     MyGizmoClass *myGizmoClass= [MyGizmoClass sharedManager];

     int b = 0;

     b = b + [myGizmoClass c];

     [myGizmoClass release]

     return b;
}
Run Code Online (Sandbox Code Playgroud)

(我还没有测试过上面的代码)

换句话说,调用MyGizmoClass*myGizmoClass = [MyGizmoClass sharedManager]有什么问题; 来自function_b,当你还没有发布MyGizmoClass*myGizmoClass = [MyGizmoClass sharedManager]; 来自function_a?

Ale*_*ski 5

问题是你使用单身人士的方式.一般的想法是你没有retainrelease任何单件对象,因为只有一个实例挂起,而单例的Apple实现是以你不能的方式编码的.这带来了Peter Hosey 更好地实现Cocoa单例时发表的一些问题.

Analyzer记录的警告只是声明您"不应该"保留或释放单例对象; 由于你打电话给[MyGizmoClass sharedManager]你不管怎么说(遵循Cocoa内存管理指南).