变量不是CFString

时间:2011-04-19 09:10:00

标签: objective-c cfstring

我正在为Ojective-C编写一个月的编码并陷入僵局。需要帮忙。 这是故事:

  1. 我有一个简单的类LXPPlayingCard:

     #import <Cocoa/Cocoa.h>
     @interface LXPPlayingCard : NSObject {
     @private NSString* cardCV;
     @private int position;
     }
    
     @property (readwrite, assign) NSString* cardCV;
     @property (readwrite,assign) int position;
     @end
    
     @implementation LXPPlayingCard
     @synthesize cardCV;
     @synthesize position;
     @end
    
  2. 我也没有更复杂的LXPDeck类:

    #import <Cocoa/Cocoa.h>
    #import "LXPPlayingCard.h"
    @interface LXPDeck : NSObject {
    LXPPlayingCard* cards[100];
    int deckCapacity;
    }
    
    -(void) fill:(NSString *) cardlist;
    -(void) showList;
    -(int) deckCapacity;
    
    @end
    
    #import "LXPDeck.h"
    #import "LXPPlayingCard.h" 
    @implementation LXPDeck
    -(void) fill:(NSString *) cardlist {
        int l,i,j;
        l=[cardlist length];
        j=0;
        for (i=0;i<l;i+=2) {
            cards[j]=[[LXPPlayingCard alloc] init] ;        
            [cards[j] setCardCV:[cardlist substringWithRange:NSMakeRange(i,2)]];
            [cards[j] setPosition:j+1];
            NSLog(@"%@",[cards[j] cardCV]);
            j++;
        }
      deckCapacity=j;
      }
    
      -(int) deckCapacity { return deckCapacity;}
    
      -(void) showList {
      NSLog(@"deck capacity:%d",deckCapacity);
      NSString * temp;
      temp=[[NSString alloc] init];
      for (int i=0;i<deckCapacity;i++) {
        NSLog(@"card[%d]=%d, adress:%p",i,[cards[i] position],cards[i]);
        temp=[cards[i] cardCV];
        NSLog(@"%@",temp);
        }
         }
    
     @end
    
  3. 做了几件事:用字符串填充名称(setCardCV)的卡片组,并打印卡片的内容(showList)。 我进一步创建了一个AppController类:

    @interface LXPAppController : NSObject {
    
    }
    -(IBAction) openNewDeck:(NSButton * )sender;
    -(IBAction) printDeckContent:(NSButton *)sender ;
    
    @end
    
    #import "AppController.h"
    #import "LXPDeck.h"
    
    
    @implementation LXPAppController
        BOOL deckOpened=FALSE;
        LXPDeck* workDeck;
    
    -(IBAction) openNewDeck:(NSButton *) sender{
    
        if (!deckOpened) {
            NSLog(@"Opening new deck...");
            workDeck=[LXPDeck alloc];
            [workDeck fill:@"pacataca"];
        }
    
        deckOpened=TRUE;
    }
    -(IBAction) printDeckContent:(NSButton *) sender {
    
        if (deckOpened) {
            NSLog(@"Printing deck content...");
            [workDeck showList];
        }
    }
    @end
    

    和主窗口上的两个按钮,我链接到openNewDeckprintDeckContent方法。 问题是应用程序因错误“EXC_BAD_ACCESS”而失败,并且它发生在i = 3上,因为(当我使用调试器时)[card[i] cardCV]不是CFString。

    我尝试使用不同的字符串来填充套牌,有时程序在显示[cards[i] cardCV]的第一圈时失败了。 我真的不明白会发生什么,但我想它以某种方式与指针和内存分配规则相关联,因为简单类型的数据(例如position)没有问题,showList方法正常工作它从fill方法调用。 拜托,帮我一把!我疯了!该程序非常简单,我对未来编码中的问题感到非常紧张......

1 个答案:

答案 0 :(得分:0)

问题在于

[cardlist substringWithRange:NSMakeRange(i,2)]]

返回您不拥有的NSString。由于您不拥有它,因此无法保证该字符串在LXPPlayingCard对象的生命周期内有效。如果要保留对该字符串的有效引用,则应修改LXPPlayingCard的声明,以使cardCV属性成为copy属性而不是assign属性。替换:

@property (readwrite, assign) NSString* cardCV;

使用:

@property (readwrite, copy) NSString* cardCV;

通过执行此操作,当您发送-setCardCV:时:

[cards[j] setCardCV:[cardlist substringWithRange:NSMakeRange(i,2)]];

setCardCV将复制其参数[cardlist substringWithRange:NSMakeRange(i,2)],您的对象将拥有该字符串的所有权。这意味着该字符串将在该对象的整个生命周期内保持有效。请记住,因为你已经取得了该字符串的所有权,所以你负责释放它。因此,您需要实现-dealloc方法:

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

这意味着当释放相应的LXPPlayingCard时,cardCV中存储的字符串也会被释放。