Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/111.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 属性、线程、内存管理和Rock&;滚_Ios_Objective C_Multithreading_Memory Management - Fatal编程技术网

Ios 属性、线程、内存管理和Rock&;滚

Ios 属性、线程、内存管理和Rock&;滚,ios,objective-c,multithreading,memory-management,Ios,Objective C,Multithreading,Memory Management,环境:Mac OS X 10.9,Xcode 5.0.2,ARC禁用 问题:如何在所有线程完成作业后释放属性内存。见下面的例子 我正在用一个按钮创建一个小示例“(iAction)btnRun:(id)sender”。 示例读取txt文件并填充NSArray属性(sharedListWords)。然后运行两个线程,每个线程显示单词,请参见第节。当线程完成作业时,属性(self.sharedListWords)不会被释放!但我需要为(self.sharedListWords)属性分配的可用内存。操作

环境:Mac OS X 10.9,Xcode 5.0.2,ARC禁用

问题:如何在所有线程完成作业后释放属性内存。见下面的例子

我正在用一个按钮创建一个小示例“(iAction)btnRun:(id)sender”。 示例读取txt文件并填充NSArray属性(sharedListWords)。然后运行两个线程,每个线程显示单词,
请参见第节。当线程完成作业时,属性(self.sharedListWords)不会被释放!但我需要为(self.sharedListWords)属性分配的可用内存。操作“btnRun”在线程完成作业之前退出,在此操作中我无法释放(self.sharedListWords)

线程完成作业后如何释放属性(self.sharedListWords)的内存?通过创建依赖项操作jobFinished(),回答是很好,但如何正确释放属性?

这是我在Objective-c上的第一个多线程程序,我将很高兴进行调整


AppDelegate.h:

#import <Cocoa/Cocoa.h>

@interface AppDelegate : NSObject <NSApplicationDelegate>
{
    volatile int32_t sharedIndex;   // Shared between threads, current index in array
    NSOperationQueue* operationQueue;
}
@property (assign) IBOutlet NSWindow *window;
// Shared between threads, list of words
@property (atomic, retain) NSArray* sharedListWords;
- (void)worker;

@end
    #import <Cocoa/Cocoa.h>

    @interface AppDelegate : NSObject <NSApplicationDelegate>
    {
        volatile int32_t sharedIndex;   // Shared between threads, current index in array
        NSOperationQueue* operationQueue;
    }
    @property (assign) IBOutlet NSWindow *window;
    // Shared between threads, list of words
    @property (atomic, retain) NSArray* sharedListWords;
    - (void)worker;

    @end
#导入
@接口AppDelegate:NSObject
{
volatile int32_t sharedIndex;//线程之间共享,数组中的当前索引
NSOperationQueue*操作队列;
}
@属性(分配)窗口*窗口;
//线程间共享,单词列表
@属性(原子,保留)NSArray*sharedListWords;
-(b)工人;
@结束
AppDelegate.m:

#import "AppDelegate.h"

@implementation AppDelegate

- (IBAction)btnRun:(id)sender
{
    // Read txt file dictionary of words, where is each words in new line.
    NSString* dictionaryFilePath = [NSString stringWithFormat:@"/Users/admin/dictionary.txt"];
    NSString* fileContents = [NSString stringWithContentsOfFile:dictionaryFilePath
                                                       encoding:NSUTF8StringEncoding error:nil];
    // Get array of string separated by new line
    self.sharedListWords = [fileContents componentsSeparatedByCharactersInSet:
                                [NSCharacterSet newlineCharacterSet]];

    //self.sharedListWords = @[@"one",@"two",@"three",@"four",@"five",@"six",@"seven",@"eight",@"nine",@"ten"];

    self->sharedIndex = -1;

    int numberOfThreads = 2;

    // Run method working() in separate threads
    for(int i=0; i<numberOfThreads; ++i)
    {
        //////////////////////////////////////////
        // Create a thread
        // Create new NSOperatin object with function puting in @selector() for run in other thread.
        NSOperation* startBruteOper = [[NSInvocationOperation alloc]
                                       initWithTarget:self selector:@selector(worker) object:nil];
        // Add the operation to the queue and let it to be executed.
        [operationQueue addOperation:startBruteOper];
        [startBruteOper release];
        /////////////////////////////////////////
    }
}

- (void)worker
{
    unsigned long countWords = [self.sharedListWords count];

    int32_t index = 0;

    // Use atomic operation for thread safe
    while( (index = OSAtomicIncrement32( &(self->sharedIndex) ) ) < countWords )
    {
        NSLog(@"[%@] working on \"%@\"",
              [NSThread currentThread],
              [self.sharedListWords objectAtIndex:index]);
    }

    NSLog(@"[%@] work is finish.", [NSThread currentThread]);
}

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
    // Multithreading queue list
    operationQueue = [[NSOperationQueue alloc] init];
}

@end
    #import "AppDelegate.h"

    @implementation AppDelegate

    - (IBAction)btnRun:(id)sender
    {
        // Read txt file dictionary of words, where is each words in new line.
        NSString* dictionaryFilePath = [NSString stringWithFormat:@"/Users/admin/dictionary.txt"];
        NSString* fileContents = [NSString stringWithContentsOfFile:dictionaryFilePath
                                                           encoding:NSUTF8StringEncoding error:nil];
        // Get array of string separated by new line
        self.sharedListWords = [fileContents componentsSeparatedByCharactersInSet:
                                    [NSCharacterSet newlineCharacterSet]];

        //self.sharedListWords = @[@"one",@"two",@"three",@"four",@"five",@"six",@"seven",@"eight",@"nine",@"ten"];

        self->sharedIndex = -1;

        int numberOfThreads = 2;

        NSOperation* jobFinishedOper = [[NSInvocationOperation alloc]
                                    initWithTarget:self selector:@selector(jobFinished) object:nil];

        // Run method working() in separate threads
        for(int i=0; i<numberOfThreads; ++i)
        {
            //////////////////////////////////////////
            // Create a thread
            // Create new NSOperatin object with function puting in @selector() for run in other thread.
            NSOperation* startBruteOper = [[NSInvocationOperation alloc]
                                           initWithTarget:self selector:@selector(worker) object:nil];
            // Add the operation to the queue and let it to be executed.
            [operationQueue addOperation:startBruteOper];
            [jobFinishedOper addDependency:startBruteOper]; // 'jobFinishedOper' run only when 'startBruteOper' finished!
            [startBruteOper release];
            /////////////////////////////////////////
        }
        // 'jobFinishedOper' run only when all prevous operation is finished!
        [operationQueue addOperation:jobFinishedOper];
        [jobFinishedOper release];
    }

    - (void)worker
    {
        unsigned long countWords = [self.sharedListWords count];

        int32_t index = 0;

        // Use atomic operation for thread safe
        while( (index = OSAtomicIncrement32( &(self->sharedIndex) ) ) < countWords )
        {
            NSLog(@"[%@] working on \"%@\"",
                  [NSThread currentThread],
                  [self.sharedListWords objectAtIndex:index]);
        }

        NSLog(@"[%@] work is finish.", [NSThread currentThread]);
    }

    - (void)jobFinished
    {
        self.sharedListWords = nil;
    }

    - (void)applicationDidFinishLaunching:(NSNotification *)aNotification
    {
        // Multithreading queue list
        operationQueue = [[NSOperationQueue alloc] init];
    }

    @end
#导入“AppDelegate.h”
@实现AppDelegate
-(iAction)btnRun:(id)发送方
{
//阅读txt文件字典中的单词,其中每一个单词都在新行中。
NSString*dictionaryFilePath=[NSString stringWithFormat:@”/Users/admin/dictionary.txt];
NSString*fileContents=[NSString stringWithContentsOfFile:dictionaryFilePath
编码:NSUTF8StringEncoding错误:nil];
//获取由新行分隔的字符串数组
self.sharedListWords=[fileContents组件由字符分隔集:
[NSCharacterSet newlineCharacterSet]];
//self.sharedListWords=@[“一”,“二”,“三”,“四”,“五”,“六”,“七”,“八”,“九”,“十];
self->sharedIndex=-1;
int numberOfThreads=2;
//在单独的线程中运行方法working()
对于(int i=0;isharedIndex))
外段:


[您可以添加另一个依赖于所有“辅助”操作的操作,如下所示:
描述于

该操作在其所有依赖项完成后运行,因此您可以调用

self.sharedListWords = nil;

在完成的操作中释放数组。

这是正确的代码,遵循Martins指令

AppDelegate.h:

#import <Cocoa/Cocoa.h>

@interface AppDelegate : NSObject <NSApplicationDelegate>
{
    volatile int32_t sharedIndex;   // Shared between threads, current index in array
    NSOperationQueue* operationQueue;
}
@property (assign) IBOutlet NSWindow *window;
// Shared between threads, list of words
@property (atomic, retain) NSArray* sharedListWords;
- (void)worker;

@end
    #import <Cocoa/Cocoa.h>

    @interface AppDelegate : NSObject <NSApplicationDelegate>
    {
        volatile int32_t sharedIndex;   // Shared between threads, current index in array
        NSOperationQueue* operationQueue;
    }
    @property (assign) IBOutlet NSWindow *window;
    // Shared between threads, list of words
    @property (atomic, retain) NSArray* sharedListWords;
    - (void)worker;

    @end
#导入
@接口AppDelegate:NSObject
{
volatile int32_t sharedIndex;//线程之间共享,数组中的当前索引
NSOperationQueue*操作队列;
}
@属性(分配)窗口*窗口;
//线程间共享,单词列表
@属性(原子,保留)NSArray*sharedListWords;
-(b)工人;
@结束
AppDelegate.m:

#import "AppDelegate.h"

@implementation AppDelegate

- (IBAction)btnRun:(id)sender
{
    // Read txt file dictionary of words, where is each words in new line.
    NSString* dictionaryFilePath = [NSString stringWithFormat:@"/Users/admin/dictionary.txt"];
    NSString* fileContents = [NSString stringWithContentsOfFile:dictionaryFilePath
                                                       encoding:NSUTF8StringEncoding error:nil];
    // Get array of string separated by new line
    self.sharedListWords = [fileContents componentsSeparatedByCharactersInSet:
                                [NSCharacterSet newlineCharacterSet]];

    //self.sharedListWords = @[@"one",@"two",@"three",@"four",@"five",@"six",@"seven",@"eight",@"nine",@"ten"];

    self->sharedIndex = -1;

    int numberOfThreads = 2;

    // Run method working() in separate threads
    for(int i=0; i<numberOfThreads; ++i)
    {
        //////////////////////////////////////////
        // Create a thread
        // Create new NSOperatin object with function puting in @selector() for run in other thread.
        NSOperation* startBruteOper = [[NSInvocationOperation alloc]
                                       initWithTarget:self selector:@selector(worker) object:nil];
        // Add the operation to the queue and let it to be executed.
        [operationQueue addOperation:startBruteOper];
        [startBruteOper release];
        /////////////////////////////////////////
    }
}

- (void)worker
{
    unsigned long countWords = [self.sharedListWords count];

    int32_t index = 0;

    // Use atomic operation for thread safe
    while( (index = OSAtomicIncrement32( &(self->sharedIndex) ) ) < countWords )
    {
        NSLog(@"[%@] working on \"%@\"",
              [NSThread currentThread],
              [self.sharedListWords objectAtIndex:index]);
    }

    NSLog(@"[%@] work is finish.", [NSThread currentThread]);
}

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
    // Multithreading queue list
    operationQueue = [[NSOperationQueue alloc] init];
}

@end
    #import "AppDelegate.h"

    @implementation AppDelegate

    - (IBAction)btnRun:(id)sender
    {
        // Read txt file dictionary of words, where is each words in new line.
        NSString* dictionaryFilePath = [NSString stringWithFormat:@"/Users/admin/dictionary.txt"];
        NSString* fileContents = [NSString stringWithContentsOfFile:dictionaryFilePath
                                                           encoding:NSUTF8StringEncoding error:nil];
        // Get array of string separated by new line
        self.sharedListWords = [fileContents componentsSeparatedByCharactersInSet:
                                    [NSCharacterSet newlineCharacterSet]];

        //self.sharedListWords = @[@"one",@"two",@"three",@"four",@"five",@"six",@"seven",@"eight",@"nine",@"ten"];

        self->sharedIndex = -1;

        int numberOfThreads = 2;

        NSOperation* jobFinishedOper = [[NSInvocationOperation alloc]
                                    initWithTarget:self selector:@selector(jobFinished) object:nil];

        // Run method working() in separate threads
        for(int i=0; i<numberOfThreads; ++i)
        {
            //////////////////////////////////////////
            // Create a thread
            // Create new NSOperatin object with function puting in @selector() for run in other thread.
            NSOperation* startBruteOper = [[NSInvocationOperation alloc]
                                           initWithTarget:self selector:@selector(worker) object:nil];
            // Add the operation to the queue and let it to be executed.
            [operationQueue addOperation:startBruteOper];
            [jobFinishedOper addDependency:startBruteOper]; // 'jobFinishedOper' run only when 'startBruteOper' finished!
            [startBruteOper release];
            /////////////////////////////////////////
        }
        // 'jobFinishedOper' run only when all prevous operation is finished!
        [operationQueue addOperation:jobFinishedOper];
        [jobFinishedOper release];
    }

    - (void)worker
    {
        unsigned long countWords = [self.sharedListWords count];

        int32_t index = 0;

        // Use atomic operation for thread safe
        while( (index = OSAtomicIncrement32( &(self->sharedIndex) ) ) < countWords )
        {
            NSLog(@"[%@] working on \"%@\"",
                  [NSThread currentThread],
                  [self.sharedListWords objectAtIndex:index]);
        }

        NSLog(@"[%@] work is finish.", [NSThread currentThread]);
    }

    - (void)jobFinished
    {
        self.sharedListWords = nil;
    }

    - (void)applicationDidFinishLaunching:(NSNotification *)aNotification
    {
        // Multithreading queue list
        operationQueue = [[NSOperationQueue alloc] init];
    }

    @end
#导入“AppDelegate.h”
@实现AppDelegate
-(iAction)btnRun:(id)发送方
{
//阅读txt文件字典中的单词,其中每一个单词都在新行中。
NSString*dictionaryFilePath=[NSString stringWithFormat:@”/Users/admin/dictionary.txt];
NSString*fileContents=[NSString stringWithContentsOfFile:dictionaryFilePath
编码:NSUTF8StringEncoding错误:nil];
//获取由新行分隔的字符串数组
self.sharedListWords=[fileContents组件由字符分隔集:
[NSCharacterSet newlineCharacterSet]];
//self.sharedListWords=@[“一”,“二”,“三”,“四”,“五”,“六”,“七”,“八”,“九”,“十];
self->sharedIndex=-1;
int numberOfThreads=2;
NSOperation*JobFinishedOpper=[[NSInvocationOperation alloc]
initWithTarget:自选择器:@selector(jobFinished)对象:nil];
//在单独的线程中运行方法working()
对于(int i=0;isharedIndex))
可能与Martin R>重复,我可以运行[self.sharedListWords release];在处理程序NSOperationQueue finish中?我正在测试几分钟)Martin R>我正在生成依赖处理程序jobFinished()看到更新的代码,第一次它工作正常,但当我按下第二次按钮时,它返回属性self.sharedListWords上的隔离错误。可能属性需要不同的释放?我太习惯于ARC了,以至于我几乎记不起MRC时间:-),但我认为您应该在
jobFin中分配
self.sharedListWords=nil
取消了
,而不是调用
release